L-value在使用std::map时指定const对象

l-value specifies const object while using std::map

本文关键字:const 对象 map std L-value      更新时间:2023-10-16

我正在尝试使用std::map,就像下面的例子:

#include <map>
#include <algorithm>
int wmain(int argc, wchar_t* argv[])
{
    typedef std::map<int, std::wstring> TestMap;
    TestMap testMap;
    testMap.insert(std::make_pair(0, L"null"));
    testMap.insert(std::make_pair(1, L"one"));
    testMap.erase(std::remove_if(testMap.begin(), testMap.end(), [&](const TestMap::value_type& val){ return !val.second.compare(L"one"); }), testMap.end());
    return 0;
}

和我的编译器(VS2010)给我以下消息:

>c:program filesmicrosoft visual studio 10.0vcincludeutility(260): error C2166: l-value specifies const object
1>          c:program filesmicrosoft visual studio 10.0vcincludeutility(259) : while compiling class template member function 'std::pair<_Ty1,_Ty2> &std::pair<_Ty1,_Ty2>::operator =(std::pair<_Ty1,_Ty2> &&)'
1>          with
1>          [
1>              _Ty1=const int,
1>              _Ty2=std::wstring
1>          ]
1>          e:my examplesс++language testsmaptestmaptestmaptest.cpp(8) : see reference to class template instantiation 'std::pair<_Ty1,_Ty2>' being compiled
1>          with
1>          [
1>              _Ty1=const int,
1>              _Ty2=std::wstring
1>          ]

我不明白为什么调用operator =,虽然我通过引用在lambda-function中传递val。你能解释一下我做错了什么吗?

您不能将std::remove_if与关联容器一起使用,因为该算法通过用后续的元素覆盖已删除的元素来工作:这里的问题是映射的键是常数,以防止您(或std::remove_if算法)弄乱容器的内部排序。

要有条件地从映射中删除元素,不如这样做:

for (auto iter = testMap.begin(); iter != testMap.end();)
{
    if (!iter->second.compare(L"one")) // Or whatever your condition is...
    {
        testMap.erase(iter++);
    }
    else
    {
        ++iter;
    }
}

下面是一个的实例