Hay alguna buena razón que un conjunto vacío de paréntesis (entre paréntesis) no es válido para llamar al constructor por defecto en C++?

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

MyObject  object();  //error

Me parece que el tipo de «()» automáticamente cada vez. Hay una buena razón por la que este no está permitido?

Alguien debe venir con un mejor título para este, pero no puedo pensar en lo que podría ser. Al menos deletrear «constructor» para ayudar a los motores de búsqueda(s).
Y este es otro buen ejemplo en C++ es sensible al contexto. El código de ejemplo en la pregunta sería también un error si blah sería una clase.

OriginalEl autor Martin Beckett | 2008-10-07

9 Comentarios

  1. 141

    Más desconcertantes analizar

    Esto está relacionado con lo que se conoce como «C++’s más irritantes que analizar». Básicamente, cualquier cosa que pueda ser interpretado por el compilador como una declaración de la función se interpreta 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 usted tiene C++11 y de la lista de inicialización (también conocido como el uniforme de inicialización) disponible:

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

    Con esto, no hay ninguna manera podía ser interpretado como una declaración de función.

    Pequeñeces: declarar funciones dentro de funciones. Se llama funciones en C, y al menos extern "C" foo();estilo también es permitido en C++.
    ¿Cómo puede ser interpretado como una función?
    std::vector es el tipo de retorno; v es el nombre de la función; ( se abre la lista de argumentos formales; std::istream_iterator es el tipo de primer argumento; ifs es el nombre del primer argumento, () alrededor de ifs son ignorados; en segundo lugar std::istream_iterator es el tipo de segundo argumento, que es sin nombre, () a su alrededor también son ignorados; ‘);’ cierra la lista de argumentos y la declaración de la función.
    los paréntesis después de que el segundo argumento de que no se ignoran. El segundo parámetro no es un std::istream_iterator pero un puntero o referencia a una función que no toma argumentos y devuelve un istream_iterator.
    No, esto es no la mayoría de los irritantes que analizar!!! El resto de los casos se identifican son.

    OriginalEl autor Constantin

  2. 87

    Porque es el tratado como la declaración de una función:

    int MyFunction(); //clearly a function
    MyObject object(); //also a function declaration
    Yo realmente prefiero este a la exceptuados respuesta, es una forma mucho más clara en cuanto a cuál es la causa del problema es
    Muy clara y sencilla respuesta! Al instante me fui capaz de entenderlo!

    OriginalEl autor 1800 INFORMATION

  3. 50

    La misma sintaxis que se utiliza para la declaración de la función – por ejemplo, la función object, sin tomar parámetros y devolver MyObject

    Gracias – no se me ocurre para declarar una función en th emiddle de otro código. Pero supongo que es legal.

    OriginalEl autor Nemanja Trifunovic

  4. 11

    Debido a que el compilador cree que esto es una declaración de una función que no toma argumentos y devuelve un MyObject instancia.

    OriginalEl autor Fred Larson

  5. 7

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

    MyObject object();

    es una llamada al constructor o de un prototipo de función de la declaración de una función denominada objeto con el tipo de devolución de MyObject y sin parámetros.

    OriginalEl autor Black

  6. 7

    También se podría utilizar el más detallado camino de la construcción:

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

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

    auto object1 = MyObject();
    auto object2 = MyObject(object1);
    Esto requiere un constructor de copia y es ineficiente
    El compilador es probablemente lo suficientemente inteligente como para utilizar algunos RVO-como la optimización de evitar que sea ineficiente.
    «Probablemente» significa «estoy pensando». Con respecto a la optimización de la gente por lo general no quieren adivinar, sino más bien tomar la forma explícita.
    Usted no necesita a «adivinar»; copia elisión va a suceder de aquí en todos los compiladores y ese ha sido el caso durante más de una década. No es que esto es un buen código.
    debido a que C++11 aquí se utilizará mover operador de asignación, que es más rápido para las clases, la celebración de recursos en montón.

    OriginalEl autor dalle

  7. 5

    Como se ha mencionado muchas veces, es una declaración. Es de esa manera para compatibilidad con versiones anteriores. Una de las muchas zonas de C++ que se goofy/inconsistentes/dolor/falso porque de su legado.

    OriginalEl autor Michael Burr

  8. 4

    De n4296 [dcl.init]:

    [ Nota:
    Desde () no está permitida por la sintaxis para inicializador,
    X a(); no es la declaración de un objeto de la clase X, pero el
    declaración de un función no toma ningún argumento y devuelve una X. La
    formulario () es permitido en algunos otros de inicialización de contextos (5.3.4,
    5.2.3, 12.6.2).

    —nota final ]

    Se puede añadir un enlace de la fuente?

    OriginalEl autor Andreas DM

  9. 1

    Como dijeron los demás, es una declaración de función. Debido a que C++11 puede utilizar llave de inicialización si usted necesita para ver el vacío algo que explícitamente dice que un constructor por defecto se utiliza.

    Jedi luke{}; //default constructor

    OriginalEl autor Hitokage

Dejar respuesta

Please enter your comment!
Please enter your name here