Standardkonstruktors mit leeren Klammern
-
05-07-2019 - |
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?
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