Почему std :: map ведет себя странно, когда передается по значению в лямбду? - PullRequest
3 голосов
/ 08 июня 2011

Я уже некоторое время использую c ++ 0x и очень наслаждаюсь новыми возможностями функций lamba.Я привык указывать [=] в своих лямбда-объявлениях, чтобы указать, что я хочу передавать переменные с внешней областью в свою лямбду по значению.

Однако сегодня я столкнулся с очень странной лямбда-проблемой.Я заметил, что передача карты внешней области в лямбу по значению во время for_each работает странно.Вот пример, который показывает проблему:

void LambdaOddnessOne ()
{
    map<int, wstring> str2int;
    str2int.insert(make_pair(1, L"one"));
    str2int.insert(make_pair(2, L"two"));

    vector<int> numbers;
    numbers.push_back(1);
    numbers.push_back(2);

    for_each ( numbers.begin(), numbers.end(), [=]( int num ) 
    {
        //Calling find() compiles and runs just fine
        if (str2int.find(num) != str2int.end())
        {
            //This won't compile... although it will outside the lambda
            str2int[num] = L"three";

            //Neither will this saying "4 overloads have no legal conversion for 'this' pointer"
            str2int.insert(make_pair(3, L"three"));
        }
    });

}

Многие из методов карты могут быть вызваны изнутри lamba (например, найти), но многие другие методы приводили к ошибкам компиляции, когда они компилировались просто отлично снаружиламба

Попытка использовать оператор [например, привела к:

error C2678: binary '[' : no operator found which takes a left-hand operand of type 'const std::map<_Kty,_Ty>' (or there is no acceptable conversion)

Попытка использовать функцию .insert привела к:

error C2663: 'std::_Tree<_Traits>::insert' : 4 overloads have no legal conversion for 'this' pointer

Кто-нибудь понимает, что это противоречивоповедение?Это просто проблема с компилятором MS?Я не пробовал других.

Ответы [ 2 ]

7 голосов
/ 08 июня 2011
4 голосов
/ 08 июня 2011

По умолчанию оператор вызова лямбда-функции является константным (поэтому вы не можете изменить карту, переданную по значению), но вы можете сделать ее неконстантной, написав mutable:

for_each ( numbers.begin(), numbers.end(), [=]( int num ) mutable
{
    // ...

Для получения дополнительной информации см. , почему лямбда-код C ++ 0x требует ключевого слова mutable для захвата по значению по умолчанию?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...