Por que o lambda no inicializador estático não pode acessar membros privados da classe no VC ++ 2013?
Considere o seguinte pedaço de código:
#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;
}
Considerando o padrão§ 9.4.2 / 2 Membros de dados estáticos [class.static.data]:
A expressão inicializador na definição de umstatic
O membro de dados está no escopo de sua classe.
e
§ 5.1.2 / 2 e 3 expressões lambda [expr.prim.lambda]:
2
A avaliação de uma expressão lambda resulta em um valor provisório (12.2). Esse temporário é chamado de objeto de fechamento. Uma expressão lambda não deve aparecer em um operando não avaliado (Cláusula 5). [Nota: Um objeto de fechamento se comporta como um objeto de função (20.9) .- nota final]
3
O tipo da expressão lambda (que também é o tipo do objeto de fechamento) é um tipo único e não nomeado de classe de não união - chamado tipo de fechamento - cujas propriedades são descritas abaixo. Este tipo de classe não é um agregado (8.5.1). O tipo de fechamento é declarado no menor escopo de bloco, escopo de classe ou espaço de nome que contém a expressão lambda correspondente.
Concluímos que o lambda na expressão:
int const foo::i = [&] { return foo().var; }();
pode acessar por direitoprivate
membros declass foo
uma vez que é declarado e definido na expressão inicializador dostatic
membroi
doclass foo
e, como tal, seu escopo é o escopo declass foo
.
O código compila e executa bem emGCC v4.8 eClang v3.4., no entanto, falha ao compilar no VC ++ 2013 produzindo um erro do compilador:
erro C2248: 'foo :: var': não é possível acessar o membro privado declarado na classe 'foo'
Pergunta, questão:
O comportamento acima registrado do VC ++ 2013 é um bug ou é atribuído ao comportamento específico do VC ++ 2013 que pode ser alterado pela alteração de configurações específicas do compilador?