#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()));
}
前面的代码无法编译。在标准C ++方式中,错误输出是冗长且难以理解的。关键部分似乎是这个......
/usr/include/c++/4.4/bits/stl_algobase.h:313:错误:'__result.std :: insert_iterator :: operator *中没有匹配'operator ='[与_Container = std :: set,std :: allocator&gt;]()= __first.std :: _ List_iterator :: operator * [with _Tp = std :: basic_string,std :: allocator&gt;]()'
...我实际上意味着没有定义所需的赋值运算符。我看了一下insert_iterator的源代码,并注意到它已经重载了赋值运算符。复制算法必须使用insert iterators重载赋值运算符来完成它的工作(?)。
我想这是因为我的输入迭代器是在一个字符串容器上,而我的输出迭代器是在MyContainers的容器上,重载的insert_iterator赋值运算符不再起作用。
这是我最好的猜测,但我可能错了。
那么,为什么这不起作用,我怎样才能完成我想要做的事情呢?
答案 0 :(得分:4)
使用构造函数(将更有意义而不是赋值)将起作用:
class MyContainer {
public:
string value;
MyContainer(const string& s): value(s) {
}
};
然后第二个问题是该集合还要求其内容具有可比性。
至于原因,insert_iterator
通过重载operator=
来工作:
insert_iterator<Container>& operator= (typename Container::const_reference value);
正如您所看到的,右侧值必须是容器的值类型或者可以隐式转换为它,这正是(非显式)构造函数实现的,而赋值运算符则不是。
从技术上讲,你也可以通过提供合适的转换函数来使其工作而不改变类(例如,如果你不想要非显式构造函数):
MyContainer from_string(const std::string& s)
{
MyContainer m;
m = s; //or any other method how to turn a string into MyContainer
return m;
}
可以与std::transform
一起使用:
transform(strings.begin(), strings.end(), inserter(containers, containers.end()), from_string);
答案 1 :(得分:3)
您需要添加:
1.接受字符串的构造函数(您试图将字符串添加到可以包含MyContainer对象的容器中)
2. bool运算符&lt; (set默认使用它来比较元素)
例如:
class MyContainer
{
public:
MyContainer(const string& v):value(v){};
};
bool operator <(const MyContainer &c1, const MyContainer &c2)
{
return c1.value <c2.value;
}
答案 2 :(得分:1)
问题是双重的:
MyContainer
个对象string
个对象的列表。 copy()
算法尝试将每个string
对象转换为MyContainer
对象。在C ++中添加类MyContainer
的类string
转换支持到类型MyContainer
,您需要添加一个带有string
类型参数的构造函数:
struct MyContainer {
MyContainer(const string& s) : value(s) { }
bool operator<(const MyContainer& o) const { return value < o.value; }
private:
string s;
};
您不需要赋值运算符,因为编译器可以通过copy-constructor完成复制:将string
转换为MyContainer
,然后使用默认赋值运算符指定一个MyContainer
反对另一个。但是,您需要operator<()
,因为C ++集已经过排序。