Pregunta

¿Hay alguna buena razón para que un conjunto vacío de corchetes (paréntesis) no sea válido para llamar al constructor predeterminado en C ++?

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

MyObject  object();  // error

Parece que escribo " () " automáticamente cada vez. ¿Hay alguna buena razón para que esto no esté permitido?

¿Fue útil?

Solución

El análisis más desconcertante

Esto está relacionado con lo que se conoce como el análisis más irritante de C ++. Básicamente, cualquier cosa que el compilador pueda interpretar como una declaración de función se interpretará como una declaración de función.

Otra instancia del mismo problema:

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

v se interpreta como una declaración de función con 2 parámetros.

La solución alternativa es agregar otro par de paréntesis:

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

O, si tiene C ++ 11 e inicialización de lista (también conocida como inicialización uniforme) disponible:

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

Con esto, no hay forma de que pueda interpretarse como una declaración de función.

Otros consejos

Porque se trata como la declaración para una función:

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

Se utiliza la misma sintaxis para la declaración de funciones, p. ej. la función object , sin tomar parámetros y devolviendo MyObject

Porque el compilador piensa que es una declaración de una función que no toma argumentos y devuelve una instancia de MyObject.

Supongo que el compilador no sabría si esta declaración:

  

Objeto MyObject ();

es una llamada de constructor o un prototipo de función que declara una función denominada objeto con el tipo de retorno MyObject y sin parámetros.

También puedes usar la forma de construcción más detallada:

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

En C ++ 0x, esto también permite para auto :

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

Como se mencionó muchas veces, es una declaración. Es así para la compatibilidad hacia atrás. Una de las muchas áreas de C ++ que son ridículas / inconsistentes / dolorosas / falsas debido a su legado.

Desde n4296 [dcl.init]:

  

[Nota:
Dado que () no está permitido por la sintaxis para initializer ,    X a (); no es la declaración de un objeto de clase X, sino el   Declaración de una función sin argumento y devolviendo una X. La   form () está permitido en ciertos otros contextos de inicialización (5.3.4,   5.2.3, 12.6.2).   
& # 8212; nota final]

Como dijeron los demás, es una declaración de función. Desde C ++ 11, puedes usar la inicialización de llaves si necesitas ver el algo vacío que explícitamente te dice que se usa un constructor predeterminado.

Jedi luke{}; //default constructor
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top