Reputation: 32398
I've been using c++ 0x for a while now and have been very much enjoying the new lamba function facilities. I've become accustomed to specifying [=] in my lambda declarations to indicate that I want to pass externally scoped variables into my lambda by value.
However, today I came accross a very strange lambda issue. I've noticed that passing an externally scoped map into a lamba by value during a for_each works oddly. Here's an example which shows the issue:
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"));
}
});
}
Many of map's methods could be called from inside the lamba (find for example) but lots of other methods resulted in compile errors when they'd compile just fine outside the lamba.
Attempting to use the [ operator for example resulted in:
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)
Attempting to use the .insert function resulted in:
error C2663: 'std::_Tree<_Traits>::insert' : 4 overloads have no legal conversion for 'this' pointer
Does anyone understand this inconsistent behavior? Is it just an issue with the MS compiler? I haven't tried any others.
Upvotes: 5
Views: 2485
Reputation: 28172
By default, a lambda's function call operator is const (so you cannot modify the map that is passed by value), but you can make it non-const by writing mutable
:
for_each ( numbers.begin(), numbers.end(), [=]( int num ) mutable
{
// ...
For more information, see why does C++0x's lambda require “mutable” keyword for capture-by-value, by default?
Upvotes: 4
Reputation: 15175
FYI [=]
captures by value, IIRC [&]
captures by reference.
See: C++0x lambda capture by value always const?
Upvotes: 7