I'm looking at the following code:
#include <iostream>
void f()
{
std::cout << "Called ::f()" << std::endl;
}
struct S
{
void f()
{
std::cout << "Called S::f()" << std::endl;
}
void oops()
{
[this](){ f(); }(); // calls the wrong function
}
};
int main()
{
S().oops();
return 0;
}
VS2010 calls ::f()
but GCC & VS2012 calls S::f()
. To me it seems that VS2012 is correct.
Which function should be called according to the standard?
S::f()
should be called. C++11 §5.1.2/7 states:The important part here is that "for purposes of name lookup,... the compound-statement is considered in the context of the lambda-expression." Since there is no
f
declared locally in the lambda block, it is looked up just as it would be looked up if it was referred to directly from the body ofoops
. Therefore, the member function is found.Note that recent versions of Visual C++ and gcc both have the correct behavior (including Visual C++ 2012 and gcc 4.7.2). Older versions may exhibit incorrect behavior because the lambda specification was overhauled in the second half of 2009 (see n2927: New wording for C++0x Lambdas [PDF]). Remember that before C++11 was finalized, the specification was a moving target, and older compilers are likely to implement different revisions of the specification. Even now, many implementers are still working to catch up to the final specification.