Why lambda in static initializer can't access

2019-02-24 09:08发布

Consider the following piece of code:

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

Considering the standard § 9.4.2/2 Static data members [class.static.data]:

The initializer expression in the definition of a static data member is in the scope of its class.

and

§ 5.1.2/2&3 Lambda expressions [expr.prim.lambda]:

2 The evaluation of a lambda-expression results in a prvalue temporary (12.2). This temporary is called the closure object. A lambda-expression shall not appear in an unevaluated operand (Clause 5). [ Note: A closure object behaves like a function object (20.9).-end note]

3 The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type - called the closure type - whose properties are described below. This class type is not an aggregate (8.5.1). The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression.

We end up to conclusion that the lambda in the expression:

int const foo::i = [&] { return foo().var; }();

can rightfully access private members of class foo since it is declared and defined in the initializer expression of the static member i of class foo, and as such its scope is the scope of class foo.

The code compiles and runs fine in GCC v4.8 and Clang v3.4., however it fails to compile in VC++2013 producing a compiler error:

error C2248: 'foo::var' : cannot access private member declared in class 'foo'

Question:

  • Is the above recorded behaviour of VC++2013 a bug, or it is attribute to specific VC++2013 behaviour that could be altered by changing specific compiler settings?

0条回答
登录 后发表回答