Function name resolution in a lambda that captures _this_ [closed]

这一生的挚爱 提交于 2019-12-23 18:27:07

问题


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

(http://ideone.com/w7nyb)

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?


回答1:


S::f() should be called. C++11 §5.1.2/7 states:

The lambda-expression's compound-statement yields the function-body of the function call operator, but for purposes of name lookup, determining the type and value of this and transforming id-expressions referring to non-static class members into class member access expressions using (*this), the compound-statement is considered in the context of the lambda-expression.

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 of oops. 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.



来源:https://stackoverflow.com/questions/12905539/function-name-resolution-in-a-lambda-that-captures-this

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!