【发布时间】:2014-08-08 00:23:21
【问题描述】:
考虑以下代码:
#include <iostream>
class foo {
int var = 99;
public:
static int const i;
};
int const foo::i = [&] { return foo().var; }();
auto main() -> int {
std::cout << foo::i << std::endl;
return 0;
}
考虑标准§ 9.4.2/2 静态数据成员 [class.static.data]:
中的初始化表达式
static数据成员的定义在其类的范围内。
和
§ 5.1.2/2&3 Lambda 表达式 [expr.prim.lambda]:
2对 lambda 表达式的求值会产生一个临时纯右值 (12.2)。这个临时对象称为闭包对象。 lambda 表达式不应出现在未计算的操作数中(第 5 条)。 [注意:闭包对象的行为类似于函数对象(20.9)。-结束注释]
3lambda 表达式的类型(也是闭包对象的类型)是唯一的、未命名的非联合类类型——称为闭包类型——其属性如下所述。此类类型不是聚合 (8.5.1)。闭包类型在包含相应 lambda 表达式的最小块作用域、类作用域或命名空间作用域中声明。
我们最终得出结论,表达式中的 lambda:
int const foo::i = [&] { return foo().var; }();
可以正确访问class foo 的private 成员,因为它是在class foo 的static 成员i 的初始化表达式中声明和定义的,因此它的范围是class foo 的范围.
代码在GCC v4.8 和Clang v3.4 中编译并运行良好,但在VC++2013 中编译失败,产生编译器错误:
错误 C2248:“foo::var”:无法访问在“foo”类中声明的私有成员
问题:
- 上面记录的 VC++2013 行为是否是一个错误,或者它是特定 VC++2013 行为的属性,可以通过更改特定的编译器设置来改变?
【问题讨论】:
-
这看起来很熟悉,实际上是一个错误。
-
两天前没有关于这个的问题吗?
-
@Praetorian:昨天有this,OP 回答了。这个问题是关于为什么/是否 VS 不合规。
-
Aghaghaghaghaga @40two stop hindering my search efforts! 以为我终于有了它
-
@Praetorian “如果有疑问,VS 有问题。”哈哈
标签: c++ visual-c++ c++11 lambda visual-studio-2013