C++与插入迭代器和重载运算符相关的STL问题
#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=' 不匹配 [with _Container = std::set, std::分配器 >]() = __first.std::_List_iterator::operator* [with _Tp = std::basic_string, std::allocator >]()'
...我的解释是,所需的赋值运算符未定义。我查看了 insert_iterator 的源代码,发现它重载了赋值运算符。复制算法必须使用插入迭代器重载赋值运算符来完成其工作(?)。
我猜想,因为我的输入迭代器位于字符串容器上,而输出迭代器位于 MyContainers 容器上,所以重载的 insert_iterator 赋值运算符无法再工作。
这是我最好的猜测,但我可能是错的。
那么,为什么这不起作用以及我怎样才能完成我想要做的事情呢?
#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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有效的方法是使用构造函数(这比赋值更有意义):
那么第二个问题是 set 还要求其内容具有可比性。
至于原因,
insert_iterator
通过重载operator=
来工作:如您所见,右侧值必须是容器的值类型或者可以隐式转换为它,这这正是(非显式)构造函数实现的目标,而赋值运算符则无法实现。
从技术上讲,您还可以通过提供合适的转换函数使其在不更改类的情况下工作(例如,如果您不需要非显式构造函数):
该函数可以与 std::transform 一起使用:
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_iterator
works 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
:您需要添加:
1. 接受字符串的构造函数(您正在尝试将字符串添加到可以包含 MyContainer 对象的容器)。
2. 布尔运算符 < (set默认使用它来比较元素)
例如 :
You need to add:
1. Constructor that takes string (you are trying to add string to container that can contain MyContainer objects).
2. bool operator < (set uses it by default to compare elements)
For instance :
问题是双重的:
string
对象列表中填充一组MyContainer
对象。copy()
算法尝试将每个string
对象转换为MyContainer
对象。在 C++ 中,要向MyContainer
类添加从string
类型到MyContainer
类型的转换支持,您需要添加一个采用类型参数的构造函数>string
:不需要赋值运算符,因为编译器可以通过复制构造函数完成复制:将
string
转换为MyContainer
然后使用默认的赋值运算符将一个MyContainer
对象分配给另一个对象。但是,您将需要一个operator<()
,因为 C++ 集合是排序的。The problem is twofold:
MyContainer
objectsstring
objects.The
copy()
algorithm tries to convert eachstring
object to aMyContainer
object. In C++ to add to classMyContainer
conversion support from typestring
to typeMyContainer
you need to add a constructor that takes a parameter of typestring
:You don't need an assignment operator, because the compiler can get the copying done by the copy-constructor: convert a
string
to aMyContainer
and then use the default assignment operator to assign oneMyContainer
object onto the other. You will, however need anoperator<()
because C++ sets are sorted.