Erro de palavra-chave 'explícito' do Visual Studio 2013?
Considere o seguinte programa:
#include <iostream>
class A
{
public:
A( ) { std::cout << "A()\n"; }
A( A& ) = delete;
A( int i ) { std::cout << "A( " << i << " )\n"; }
explicit operator int( ) { std::cout << "operator int()\n"; return 42; }
};
template< typename T = A > void f( T a = A() ) {}
int main( void )
{
f();
return 0;
}
O Visual Studio 2013 compila esse código e é executado com a saída
A()
operator int()
A( 42 )
Isso é um bug do compilador? Parece que o compilador VS não presta atenção à palavra-chave 'explícita' neste contexto. Pelo que entendi, o VS 2013 usa incorretamente o operador int () em combinação com A (int) para classificar 'copy-construct' A como o parâmetro padrão para f.
Ambos adicionando
A a;
A a1( a );
para principal e declarar f como
void f( A a = A() ) {}
não compila, VS reclama que A (A &) é excluído, o que parece ser um comportamento correto. Somente no contexto do parâmetro padrão do modelo de função, a combinação do operador int () e A (int) parece funcionar como uma substituição para A (A & A).
g ++ 4.7.3 não compila o código e reclama:
main.cpp: In function ‘int main()’:
main.cpp:21:7: error: no matching function for call to ‘A::A(A)’
main.cpp:21:7: note: candidates are:
main.cpp:10:3: note: A::A(int)
main.cpp:10:3: note: no known conversion for argument 1 from ‘A’ to ‘int’
main.cpp:6:3: note: A::A()
main.cpp:6:3: note: candidate expects 0 arguments, 1 provided
Remover 'explícito' faz g + + compilar o código e a saída é a mesma.