2013-06-12 7 views
5

Ich studiere 11 C++ und ich auf einheitlichen initializers stolperte.drängendsten Parsen Verwirrung

ich nicht den folgenden Code verstehen, die die "drängendsten Parse" Mehrdeutigkeit zeigen sollte:

#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 die zweite Zeile ruft den MVP auf, der erste nicht. –

+0

Ich weiß das, aber ich bin verwirrt mit den Typen im Code –

Antwort

9

hier:

auto dv = Timer(); 

Sie haben ein Objekt vom Typ Timer genannt dv, die ist Copy-initialisiert von einem temporären (der Ausdruck auf der rechten Seite der = Zeichen).

Wenn Sie verwenden, um eine Variable zu deklarieren, ist der Typ dieser Variablen der gleiche wie der Typ des Ausdrucks, der ihn initialisiert - ohne Berücksichtigung von CV-Qualifikationsmerkmalen und Verweisen hier.

In Ihrem Fall, dass der Ausdruck dv initialisiert hat Timer geben, und so hat dvTimer geben.

hier:

int time_keeper(Timer()); 

Sie deklarieren eine Funktion namens time_keeper, die eine int und nimmt als seine Eingabe liefert einen Zeiger auf eine Funktion, die eine Timer zurückgibt und kein Argument.

Und warum ist nicht das Argument Timer (*)()?

Funktionen Verfall Zeiger, wenn als Argument übergeben, so dass die Art der time_keeper ist eigentlich int(Timer(*)()).

überzeugen Sie sich selbst, Sie könnten versuchen, dieses kleine Programm kompiliert:

#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!"); 
} 

hier ein live example ist.

+0

Danke, sollte das Argument nicht "Timer (*)()" sein? Ist "Timer()" auch ein akzeptabler Funktionszeiger? –

+1

Ich denke, das ist der Fall, wenn 'functionName' und' & functionName' dasselbe sind. – Spook

+0

@DavidKernin: Funktionen werden automatisch in Zeiger umgewandelt, wenn sie als Funktionsargumente verwendet werden, also sind 'void (Timer())' und 'void (Timer (*)())' identische Typen. –

-4

alle hier ist gut, du bist nur jedes Mal eine Instanz Timer bekommen.

für sie eine Funktion Erklärung sein, um es von der Form

Timer name(); 

in diesem Fall sein muss, Sie instanziiert nichts, die richtige Syntax in diesem Fall Wesen:

Timer name; 
+0

-1: Nein, es ist nicht gut. 'time_keeper' ist eine Funktion. Das gibt ein 'int' zurück und nimmt ein Argument vom implizit-verfallenen-Zeiger-Typ an, um die Funktion" nimm-keine-Argumente-und-zurück-Timer "zu nehmen. – Angew