construtor padrão com suportes vazios
-
05-07-2019 - |
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?
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