当使用std::make_pair时,L-value指定const对象

l-value specifies const object when using std::make_pair

本文关键字:L-value 指定 对象 const std make pair      更新时间:2023-10-16
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函数。但它仍然没有消失。有人能告诉我这个错误是怎么回事吗?

问题是std::transform()将尝试分配给目标容器的现有元素。map的键是常量,不能赋值,这就是为什么会出现编译错误。但是,即使它们是,在运行时也会得到未定义的行为,因为目标容器是空的,并且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);
//                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

下面是一个的实例

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

std::pair<int, std::string> operator()(std::string value)
{
    return {count++, std::move(value)};
}

由于std::pair的构造函数不是explicit,因此在本例中甚至不需要调用std::make_pair()