Constructor predeterminado con corchetes vacíos


¿Hay alguna buena razón para que un conjunto vacío de corchetes redondos (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 una buena razón por la que esto no está permitido?

Author: Jarod42, 2008-10-08

9 answers

El análisis más molesto

Esto está relacionado con lo que se conoce como "el análisis más molesto de C++". Básicamente, cualquier cosa que pueda ser interpretada por el compilador como una declaración de función será interpretada 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 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 y lista-inicialización (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 manera de que pueda interpretarse como una declaración de función.

 139
Author: Constantin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-29 23:34:22

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

int MyFunction(); // clearly a function
MyObject object(); // also a function declaration
 86
Author: 1800 INFORMATION,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-07 20:15:41

La misma sintaxis se usa para la declaración de funciones-por ejemplo, la función object, sin tomar parámetros y devolviendo MyObject

 50
Author: Nemanja Trifunovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-07 20:15:22

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

 10
Author: Fred Larson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-07 20:15:25

También podría usar la forma más detallada de construcción:

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

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

auto object1 = MyObject();
auto object2 = MyObject(object1);
 7
Author: dalle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-08 08:05:08

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

MyObject object ();

Es una llamada de constructor o un prototipo de función que declara una función llamada objectcon el tipo de retorno myObject y sin parámetros.

 6
Author: Black,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-07 20:17:11

Como se mencionó muchas veces, es una declaración. Es así para la compatibilidad con versiones anteriores. Una de las muchas áreas de C++ que son bobas/inconsistentes/dolorosas / falsas debido a su legado.

 5
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-07 21:34:19

De n4296 [dcl.init]:

[Nota:
Dado que () no está permitido por la sintaxis para inicializador, X a(); no es la declaración de un objeto de clase X, sino declaración de una función que no toma ningún argumento y devuelve una X. form () está permitido en otros contextos de inicialización (5.3.4, 5.2.3, 12.6.2).
-nota final ]

 3
Author: Andreas DM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-27 20:09:36

Como dijeron los demás, es una declaración de función. Desde C++11 puede usar la inicialización de llaves si necesita ver el algo vacío que le indique explícitamente que se utiliza un constructor predeterminado.

Jedi luke{}; //default constructor
 1
Author: Hitokage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-19 07:11:57