2013-06-12 15 views
5

Sto studiando C++ 11 e mi sono imbattuto in inizializzatori uniformi.La maggior parte fastidiosa parse confusione

Non capisco il seguente codice che dovrebbe mostrare il "più fastidioso parse" ambiguità:

#include<iostream> 


class Timer 
{ 
public: 
    Timer() {} 
}; 

int main() 
{ 

    auto dv = Timer(); // What is Timer() ? And what type is dv? 

    int time_keeper(Timer()); // This is a function right? And why isn't the argument " Timer (*)()" ? 



    return 0; 
} 
+0

AFAIK la seconda riga richiama l'MVP, il primo no. –

+0

Lo so, ma sono confuso con i tipi coinvolti nel codice –

risposta

9

Qui:

auto dv = Timer(); 

Hai un oggetto di tipo Timer chiamato dv che è essendo inizializzato da una copia temporanea (l'espressione sul lato destro del segno =).

Quando si utilizza auto per dichiarare una variabile, il tipo di tale variabile è uguale al tipo dell'espressione che lo inizializza, non considerando i qualificatori e i riferimenti cv qui.

Nel tuo caso, l'espressione che inizializza dv ha tipo Timer e così dv ha tipo Timer.

Qui:

int time_keeper(Timer()); 

si dichiara una funzione chiamata time_keeper che restituisce un int e prende come input un puntatorea una funzione che restituisce un Timer e prende alcun argomento.

E perché non è l'argomento Timer (*)()?

Funzioni decadimento ai puntatori quando passato come argomento, quindi il tipo di time_keeper è effettivamente int(Timer(*)()).

Per convincersi, si potrebbe provare la compilazione di questo piccolo programma:

#include <type_traits> 

struct Timer { }; 
int main() 
{ 
    int time_keeper(Timer()); 
    static_assert(
     std::is_same< 
      decltype(time_keeper), 
      int(Timer(*)()) 
     >::value, 
     "This should not fire!"); 
} 

Ecco un live example.

+0

Grazie, l'argomento non dovrebbe essere "Timer (*)()"? "Timer()" è anche un indicatore di funzione accettabile? –

+1

Suppongo, questo è il caso di 'functionName' e' & functionName' sono la stessa cosa. – Spook

+0

@DavidKernin: le funzioni decadono automaticamente ai puntatori quando vengono utilizzate come argomenti di funzione, quindi 'void (Timer())' e 'void (Timer (*)())' sono tipi identici. –

-4

tutto qui è buono, stai solo ricevendo un'istanza di Timer ogni volta.

per essere una dichiarazione di funzione deve essere della forma

Timer name(); 

in questo caso, non si crea un'istanza nulla, la sintassi corretta in quel caso essere:

Timer name; 
+0

-1: No, non va bene. 'time_keeper' è una funzione. Che restituisce un 'int' e accetta un argomento di tipo implicitamente-decayed-pointer-to function-taking-no-arguments-and-return-Timer. – Angew

Problemi correlati