#include <list>
#include <set>
#include <iterator>
#include <algorithm>
using namespace std;
class MyContainer {
public:
string value;
MyContainer& operator=(const string& s) {
this->value = s;
return *this;
}
};
int main()
{
list<string> strings;
strings.push_back("0");
strings.push_back("1");
strings.push_back("2");
set<MyContainer> containers;
copy(strings.begin(), strings.end(), inserter(containers, containers.end()));
}
The preceeding code does not compile. In standard C++ fashion the error output is verbose and difficult to understand. The key part seems to be this…
/usr/include/c++/4.4/bits/stl_algobase.h:313: error: no match for ‘operator=’ in ‘__result.std::insert_iterator::operator* [with _Container = std::set, std::allocator >]() = __first.std::_List_iterator::operator* [with _Tp = std::basic_string, std::allocator >]()’
…which I interpet to mean that the assignment operator needed is not defined. I took a look at the source code for insert_iterator and noted that it has overloaded the assignment operator. The copy algorithm must uses the insert iterators overloaded assignment operator to do its work(?).
I guess that because my input iterator is on a container of strings and my output iterator is on a container of MyContainers that the overloaded insert_iterator assignment operator can no longer work.
This is my best guess, but I am probably wrong.
So, why exactly does this not work and how can I accomplish what I am trying to do?
What would work would be using the constructor (which would make more sense instead of the assignment):
Then the second problem is that set also requires its contents to be comparable.
As to the cause,
insert_iteratorworks by overloadingoperator=:As you can see, the righthand value must be either the value type of the container or implicitly convertible to it, which is exactly what a (non-explicit) constructor achieves and the assignment operator doesn’t.
Technically you could also make it work without changing the class (e.g if you don’t want an non-explicit constructor) by providing a suitable conversion function:
which can be used with
std::transform: