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?
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.
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
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
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.
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);
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.
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.
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 ]
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
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