struct MapInserter
{
private:
int count;
public:
explicit MapInserter()
: count(0)
{
}
std::pair<int, std::string> operator()(std::string& value)
{
return std::make_pair(count++, value);
}
};
vector<std::string> words = { "one", "two", "three","four","five" };
std::map<int, std::string> map;
MapInserter inserter;
transform(words.begin(), words.end(), map.begin(), inserter);
for (auto it = map.begin(), end = map.end(); it != end; ++it)
cout << it->first << " : " << it->second << endl;
return 0;
这就是代码。 VS返回有关l-value specifies const object
的编译错误。
单击该错误会将您移至名为utility
的文件中的以下代码template<class _Other1,
class _Other2>
_Myt& operator=(pair<_Other1, _Other2>&& _Right)
{ // assign from moved compatible pair
first = _STD forward<_Other1>(_Right.first);
second = _STD forward<_Other2>(_Right.second);
return (*this);
}
首先,我已经operator()
取const std::string&
所以我删除了const,因为它显然是在谈论make_pair函数。但它仍然没有消失。谁能指出我这个错误是什么?
答案 0 :(得分:6)
问题是std::transform()
会尝试将分配给目标容器的现有元素。映射的键是常量,无法分配,这就是您收到编译器错误的原因。但即使它们是,你在运行时也会得到未定义的行为,因为目标容器是空的,std::transform()
期望它包含与输入范围一样多的元素。
您应该使用std::inserter()
创建一个插入器迭代器,如下所示:
vector<std::string> words = { "one", "two", "three","four","five" };
std::map<int, std::string> map;
MapInserter inserter;
transform(words.begin(), words.end(), std::inserter(map, map.begin()), inserter);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
这是live example。
此外,在value
的调用运算符中使用MapInserter
字符串中的可变左值引用不是一个好主意:您不希望修改参数,所以你应该或者通过const&
或者 - 我的建议 - 按值获取它,然后将其移动到返回的对中,如下所示:
std::pair<int, std::string> operator()(std::string value)
{
return {count++, std::move(value)};
}
由于std::pair
的构造函数不是explicit
,因此在这种情况下您甚至不需要调用std::make_pair()
。