Frage

Gibt es einen guten Grund, dass ein leerer Satz von runden Klammern (Klammern) für den Aufruf der Standard-Konstruktor in C nicht gültig ++?

MyObject  object;  // ok - default ctor
MyObject  object(blah); // ok

MyObject  object();  // error

Ich scheine „()“ automatisch jedes Mal eingeben. Gibt es einen guten Grund, dies nicht erlaubt ist?

War es hilfreich?

Lösung

Die meisten ärgerlichen Parse

Dies bezieht sich auf das, was bekannt ist als „C ++" s drängendsten Parse“. Im Grunde alles, was durch den Compiler als Funktionsdeklaration interpretiert werden kann, wird als Funktionsdeklaration interpretiert werden.

Ein weiteres Beispiel aus dem gleichen Problem:

std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());

v als Erklärung der Funktion mit 2 Parametern interpretiert wird.

Die Abhilfe ist ein anderes Paar von Klammern hinzuzufügen:

std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());

Oder, wenn Sie C ++ 11 und list-Initialisierung (auch als einheitliche Initialisierung bekannt) zur Verfügung:

std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};

Damit gibt es keine Möglichkeit, es als Funktionsdeklaration interpretiert werden könnte.

Andere Tipps

Weil es die als Erklärung für eine Funktion behandelt wird:

int MyFunction(); // clearly a function
MyObject object(); // also a function declaration

Die gleiche Syntax für Funktionsdeklaration verwendet - z.B. die Funktion object, keine Parameter zu nehmen und zurückkehr MyObject

Da der Compiler denkt, dass es eine Erklärung einer Funktion, die keine Argumente nimmt und gibt eine MyObject Instanz.

Ich denke, würde der Compiler nicht wissen, ob diese Aussage:

  

MyObject Objekt ();

ist ein Konstruktor-Aufruf oder ein Funktionsprototyp eine Funktion namens Objekt mit Rückgabetyp MyObject und keine Parameter zu deklarieren.

Sie können auch die ausführlichere Konstruktionsweise verwenden:

MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);

In C ++ 0x dies ermöglicht auch auto:

auto object1 = MyObject();
auto object2 = MyObject(object1);

Wie viele Male erwähnt, ist es eine Erklärung. Es ist auf diese Weise für die Abwärtskompatibilität. Einer der vielen Bereichen der C ++, das aufgrund seiner Vermächtnis doof / inkonsistent / schmerzhafte / Schein sind.

Von n4296 [dcl.init]:

  

[Anmerkung:
Da () nicht durch die Syntax erlaubt für initializer ,   X a(); ist nicht die Deklaration eines Objekt der Klasse X, aber die   Deklaration einer Funktion kein Argument zu nehmen und Rückkehr eines X. Der   Form () ist in bestimmten anderen Zusammenhängen zulässig Initialisierung (5.3.4,   5.2.3, 12.6.2).   
-Ende note]

Wie die anderen gesagt, ist es eine Funktionsdeklaration. Da C 11 ++ können Sie Klammer Initialisierung verwenden, wenn Sie die leere sehen müssen etwas , das sagt Ihnen ausdrücklich, dass ein Default-Konstruktor verwendet wird.

Jedi luke{}; //default constructor
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top