2011-12-12 5 views
11

Duplicar posible:
Why is it an error to use an empty set of brackets to call a constructor with no arguments?C++ constructor espeluznante

Vamos a tener este código

class Foo { 
    Foo(int) { } 
}; 

entonces tenemos ahí los resultados:

int main() { 
    Foo f1 = Foo(5); // 1: OK, explicit call 
    Foo f2(5); // 2: OK, implicit call 
    Foo f3(); // 3: no error, "f3 is a non-class type Foo()", how so? 
    Foo f4(f1); // 4: OK, implicit call to default copy constructor 
    Foo f5; // 5: expected error: empty constructor missing 
} 

¿Puede explicar lo que está sucediendo en el caso ?

+13

búsqueda: vexing parse – Nim

+0

@Nim: Debería haber sido una respuesta. –

+0

También tenga en cuenta que el ejemplo 5 está haciendo lo que se esperaba del ejemplo 3 y llama al constructor predeterminado. – Joe

Respuesta

8

Foo f3(); declara una función llamada f3, con un tipo de devolución de Foo.

+0

¡Ah, por supuesto! Estaba tan concentrado en los constructores ... –

12

La tercera línea se analiza declarando una función que no toma ningún argumento y devuelve Foo.

2

Has definido una función llamada f3 que devuelve un foo en el caso 3. En el caso 5, no tienes definido un constructor predeterminado, por lo que obtienes un error.

5

C++ tiene una regla que dice que si una declaración se puede interpretar como una declaración de función, se interpreta de esta manera.

Por lo tanto, la sintaxis Foo f3(); en realidad declara una función que no toma argumentos y devuelve Foo. Trabaja esto escribiendo Foo f3;, llamará al constructor predeterminado también (si hay uno, por supuesto).

4
  • f1 invoca el constructor de copia después de una llamada explícita, que estaba equivocado en este caso
  • f2 es una llamada al constructor explícito // estabas equivocado aquí también
  • f3 declara una función
  • f4 es de nuevo el constructor de copia, como f1 // está aquí
  • f5 llamaría al constructor predeterminado // está aquí de nuevo
+0

'Foo f6 = 5;' ¿lo haría mediante una llamada de constructor implícita? IIRC. –

+0

@Douglas: Sí, eso sería correcto. – Xeo

3

Esto no es lo que creo que es:

Foo f3(); 

Usted puede pensar que esto es una llamada explícita del constructor por defecto, pero no lo es. En realidad, es una declaración de una función llamada f3 que no toma ningún parámetro y devuelve Foo por valor.

Que esto se analiza como una declaración de función en lugar de una llamada de constructor conocida como Most Vexing Parse.

+0

No, no lo es. El MVP es cuando proporcionas argumentos y aún parece una declaración de función. Este no es el MVP, es solo que el programador es tonto –