2014-10-16 17 views
5

Perché il compilatore interpretare questa linea come una definizione di funzione e non come definizione della variabile:Definizione della funzione o definizione della variabile?

Y y(X()); 

nel codice seguente:

#include <iostream> 

struct X { 
    X() { std::cout << "X"; } 
}; 

struct Y { 
    Y(const X &x) { std::cout << "Y"; } 
    void f() { std::cout << "f"; } 
}; 

int main() { 
    Y y(X()); 
    y.f(); 
} 

VS2010 dà il seguente errore on line "YF() ;"

left of '.f' must have class/struct/union 

Quale parte dello standard descrive questo comportamento? La risposta alla seguente domanda non dà dettagli su di esso: Most vexing parse

+1

Questo non è un bug del compilatore. È il problema di parse più irritante, astutamente camuffato. – Bathsheba

+1

Votato per riaprire in base alla modifica: una citazione dallo standard sarebbe effettivamente utile. 6.8 parla di dichiarazioni di espressioni disamorose e dichiarazioni, ma l'analisi più irritante è in realtà un'ambiguità tra due dichiarazioni. – Angew

risposta

6

Considerate questo:

float foo(int())

Questo dichiara una funzione foo (accettando una funzione che restituisce int) ritorno float.

ora Saperne

Y y(X()); 

come y come la funzione (accettando una funzione che restituisce X) tornando Y

Il problema sorge a causa di C++ most vexing parse

può essere risolto con:

Y y{ X() }; // requires C++11 

o

Y y((X())); 
    //^ ^notice parenthesis 

Aggiornamento sulla base di edit:

Un citazione da standard:

§ 8.2 risoluzione ambiguità [dcl.ambig.res]

1 - L'ambiguità derivante dalla somiglianza tra un cast di tipo funzione e una dichiarazione menzionata in 6.8 può anche verificarsi nel contesto di una dichiarazione. In questo contesto, la scelta è tra una dichiarazione di funzione con un insieme ridondante di parentesi attorno al nome di un parametro e una dichiarazione di oggetto con un cast di stile funzione come inizializzatore. Come per le ambiguità menzionate in 6.8, la risoluzione è considerare qualsiasi costrutto che potrebbe essere una dichiarazione una dichiarazione. [Nota: una dichiarazione può essere esplicitamente disambigua da un cast non funzionale, da a = per indicare l'inizializzazione o rimuovendo le parentesi ridondanti attorno al nome del parametro. ]

[Example: 

struct S { 
    S(int); 
}; 

void foo(double a) 
{ 
    S w(int(a)); // function declaration 
    S x(int()); // function declaration 
    S y((int)a); // object declaration 
    S z = int(a); // object declaration 
} 
—end example] 

Analogamente altri esempi seguendo questo.

+2

'Y y = X();' non è equivalente a 'Y y {X()};'. La soluzione giusta in C++ 03 è 'Y y ((X()));' – magras

+0

Tuttavia in alcuni casi 'Y y = X();' funzionerà come previsto ed è più leggibile. – magras

+0

@PetrPervukhin sì aggiornato, grazie – P0W

4

Most vexing parse problem. Y y(X()) è in realtà la dichiarazione di funzione con il nome , che restituisce Y e riceve l'argomento di tipo funzione, che restituisce X e non riceve nulla.

È risolto in C++ 11 con l'utilizzo di {} per l'oggetto di costruzione.

Problemi correlati