sky*_*ack 15 c++ lambda language-lawyer c++14
请考虑以下示例:
#include <cassert>
struct S {
auto func() { return +[](S &s) { s.x++; }; }
int get() { return x; }
private:
int x{0};
};
int main() {
S s;
s.func()(s);
assert(s.get() == 1);
}
Run Code Online (Sandbox Code Playgroud)
它用G ++和clang编译,所以我很想期望标准允许这样做.但是,lambda没有捕获列表,因为+它强制转换为函数指针,所以它不能拥有它.因此,我预计不允许访问私有数据成员S.
相反,如果它被定义为静态成员函数,它的行为或多或少.
到现在为止还挺好.如果我以前知道它,我会经常使用这个技巧来避免编写冗余代码.
我现在想知道的是标准中的位置(工作草案很好)这是定义的,因为我无法找到关于它的部分,子弹或其他任何规则.
是否有拉姆达任何限制或它的工作原理完全相同,如果它被定义为一个静态成员函数?
son*_*yao 15
对于成员函数内的lambda表达式,根据§8.4.5.1/ 2 Closure类型[expr.prim.lambda.closure]:
闭包类型在包含相应lambda表达式的最小块作用域,类作用域或命名空间作用域中声明.
这意味着lambda闭包类型将在成员函数内声明,即本地类.并根据§14/ 2成员访问控制[class.access]:
(强调我的)
类的成员还可以访问该类可以访问的所有名称.成员函数的本地类可以访问成员函数本身可以访问的相同名称.
这意味着对于λ表达式本身,它可以访问private的成员S,相同的成员函数func.
和§8.4.5.1/ 7关闭类型[expr.prim.lambda.closure]:
(强调我的)
没有lambda-capture的非泛型lambda表达式的闭包类型,其约束(如果有的话)满足了一个转换函数指向函数,C++语言链接具有与闭包类型函数调用操作符相同的参数和返回类型.... 此转换函数返回的值是函数F的地址,在调用时,它与调用闭包类型的函数调用运算符具有相同的效果.
这意味着当转换的函数指针被调用时,应用相同的规则.
但是,lambda没有捕获列表,因为
+它强制转换为函数指针,所以它不能拥有它.
+不会强制转换为函数指针,而是将转换运算符添加到指向函数的指针,以供您用作选项.Lambda仍然是lambda,具有授予它的所有访问权限,即它可以访问成员函数本身可以访问的相同名称.