l-value在使用std :: make_pair时指定const对象

Gio*_*ait 1 c++ stl

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;
Run Code Online (Sandbox Code Playgroud)

那是代码.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);
    }
Run Code Online (Sandbox Code Playgroud)

起初,我已经有operator()采取const std::string&所以我删除const的,因为它明显地谈论make_pair功能.但它仍然没有消失.谁能指出我这个错误是什么?

And*_*owl 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);
//                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

这是一个实例.

此外,value在你的调用运算符中通过可变左值引用获取字符串MapInserter不是一个好主意:你不希望修改参数,所以你应该接受它const&或者 - 我的建议 - 按值接受它然后将它移动到返回的对中,如下所示:

std::pair<int, std::string> operator()(std::string value)
{
    return {count++, std::move(value)};
}
Run Code Online (Sandbox Code Playgroud)

由于std::pair构造函数不是explicit,std::make_pair()在这种情况下你甚至不需要调用.