2015-07-02 5 views
10

È possibile definire e copia-inizializzare una variabile all'interno della condizione di un if dichiarazione:diretto inizializzare un oggetto all'interno di una condizione

if(int i = 17) { ... } 

Questo funziona anche con tipi definiti dall'utente, dato che sovraccaricano operator bool:

if(Foo f = 42)  { ... } 
if(Foo f = Foo(43)) { ... } 

Perché non posso usare-inizializzazione diretta, come la seguente?

if(Foo f(51)) { ... } 

GCC emette error: expected primary-expression before 'f'.

Live on Coliru

C'è un motivo diverso "perché la grammatica dice così"? E come posso aggirarlo?

sto lavorando con VC++ 03, dove Foo:

  • è un oggetto Raii sensibile, per la quale io non sono occupato per definire un costruttore di copia
  • è una presa modello argomenti da parte dell'utente
  • ha una due-parametri costruttore

... quindi preferisco evitare di copiare o ripetere il suo tipo.

Nota: sebbene il mio problema reale sia con C++ 03, sono (accademicamente) interessato alle risposte in C++ 11.

+0

Correlato a [Una variabile può essere definita solo nell'ambito di un'istruzione if, come avviene spesso per i cicli for?] (Http://stackoverflow.com/q/24017216/1708801) –

+0

Perché fare una variabile? pensi che la dichiarazione 'Foo f = 42' implichi una copia/mossa? Non dovresti copiare il lavoro di elision? – Columbo

+0

@Columbo AFAIK copy elision è un'ottimizzazione che può essere eseguita o meno, ma anche se non è l'oggetto ha bisogno di un costruttore di copie, che ho disabilitato per evitare il "male auto_ptr". Alla fine ho risolto il problema passando un 'std :: pair'. – Quentin

risposta

10

In C++ 03, si potrebbe usare solo la sintassi copia-inizializzazione:

selezione-dichiarazione:
        if (condizione)dichiarazione
        [...]

condizione:
        espressione
        tipo specificatore-seq declarator= assegnazione espressione

Poiché C++ 11, lista- inizializzazione aggiunta:

condizione:
        espressione
        attributo-specificatore-seq optdecl-specificatore-seq declarator=inizializzatore clausola
        attributo-specificatore-seq optdecl-specificatore-seq dichiaratore rinforzato-init-list

La sintassi di inizializzazione diretta, cioè Foo f(…), presumibilmente è stato evitato per lo stesso motivo per cui è stato disabilitato per gli inizializzatori di dati non statici: le ambiguità, in particolare la "analisi più irritante".

2

perché lo standard C++ 03 consente solo l'assegnazione di inizializzazione all'interno di condizioni:

condition: 
    expression 
    type-specifier-seq declarator = assignment-expression 
2

dato il vostro restrizioni, io credo in C++ 03 l'unica opzione è quella di dichiarare la variabile al di fuori della dichiarazione if, aggiungendo bretelle per scoping:

{ 
    Foo f(51, 52); 
    if (f) { 
     //... 
    } 
} 

in C++ 11 si potrebbero sfruttare sintassi inizializzazione Braced:

if (Foo f{51, 52}) { 
    //... 
} 
Problemi correlati