Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm trying to use std::map like in example below:

#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;
}

And my compiler (VS2010) gives me following message:

>c:\program files\microsoft visual studio 10.0\vc\include\utility(260): error C2166: l-value specifies const object

1>          c:\program files\microsoft visual studio 10.0\vc\include\utility(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 tests\maptest\maptest\maptest.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>          ]

I can't understand why opertor = is called though I pass val in lambda-function by reference. Could you explain what I am doing wrong?

like image 367
MaxP Avatar asked May 02 '13 08:05

MaxP


1 Answers

You cannot use std::remove_if with an associative container, because that algorithm works by overwriting removed elements with the subsequent ones: the problem here is that keys of a map are constant, in order to prevent you (or the std::remove_if algorithm) from messing up with the internal ordering of the container.

To remove elements from a map conditionally, rather do this:

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

Here is a live example.

like image 168
Andy Prowl Avatar answered Sep 27 '22 17:09

Andy Prowl