为什么std :: map在通过值传递给lambda时表现得很奇怪?

时间:2011-06-08 15:04:22

标签: c++ c++11

我一直在使用c ++ 0x一段时间,并且非常享受新的lamba功能设施。我习惯于在我的lambda声明中指定[=]来表示我想通过值将外部作用域的变量传递给我的lambda。

然而,今天我遇到了一个非常奇怪的lambda问题。我注意到在for_each期间通过值将外部范围的映射传递给lamba奇怪地工作。这是一个显示问题的例子:

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内部调用许多map的方法(例如find),但是当它们在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 个答案:

答案 0 :(得分:7)

答案 1 :(得分:4)

默认情况下,lambda的函数调用运算符是const(因此您无法修改按值传递的映射),但您可以通过编写mutable使其成为非const:

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

有关详细信息,请参阅why does C++0x's lambda require “mutable” keyword for capture-by-value, by default?