Pergunta

Existe alguma boa razão para que um conjunto vazio de parênteses (parênteses) não é válido para chamar o construtor padrão em C ++?

MyObject  object;  // ok - default ctor
MyObject  object(blah); // ok

MyObject  object();  // error

Eu pareço tipo "()" automaticamente sempre. Existe uma boa razão isso não é permitido?

Foi útil?

Solução

mais irritante de análise

Isto está relacionado com o que é conhecido como "C ++ 's mais parse irritante". Basicamente, qualquer coisa que possa ser interpretado pelo compilador como uma declaração de função será interpretada como uma declaração de função.

Outra instância do mesmo problema:

std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());

v é interpretado como uma declaração de função com 2 parâmetros.

A solução é adicionar um outro par de parênteses:

std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());

Ou, se você tiver C ++ 11 e lista-inicialização (também conhecido como inicialização uniforme) disponíveis:

std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};

Com isso, não há nenhuma maneira que poderia ser interpretado como uma declaração de função.

Outras dicas

Porque é o tratado como a declaração para uma função:

int MyFunction(); // clearly a function
MyObject object(); // also a function declaration

A mesma sintaxe é usado para a declaração função - por exemplo, a função object, tendo sem parâmetros e retornando MyObject

Como o compilador acha que é uma declaração de uma função que não recebe argumentos e retorna uma instância de MyObject.

Eu acho que, o compilador não saberia se esta declaração:

objecto MeuObjeto ();

é uma chamada de construtor ou um protótipo de função declarando uma função chamada objeto com tipo de retorno MyObject e sem parâmetros.

Você também pode usar o mais detalhado modo de construção:

MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);

Em C ++ 0x isso também permite auto:

auto object1 = MyObject();
auto object2 = MyObject(object1);

Como mencionado muitas vezes, é uma declaração. É dessa maneira para compatibilidade com versões anteriores. Uma das muitas áreas de C ++ que são pateta / inconsistente / / doloroso falso por causa de seu legado.

De n4296 [dcl.init]:

[Nota:
Desde () não é permitida pela sintaxe para initializer , X a(); não é a declaração de um objeto de classe X, mas o declaração de uma função ter nenhum argumento e retornando um X. A forma () é permitido em certos outros contextos de inicialização (5.3.4, 5.2.3, 12.6.2).
-end nota]

Como os outros disseram, é uma declaração de função. Desde C ++ 11 você pode usar a inicialização cinta se você precisa ver o vazio algo que explicitamente diz que um construtor padrão é usado.

Jedi luke{}; //default constructor
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top