explicit keyword
-
Hi,
warum macht der compiler ueberhaupt eine implicit type conversion wenn ich folgendes aufrufe?
Foo f1 = 2;und explicit sollte das verhindern, was nur bei 1 parameter funktioniert?
class Foo { public: explicit Foo(int x) {} }; class Bar { public: Bar(double x) {} }; int main() { Foo f1 = 2; return 0; }
-
gilt das nur wenn ich keinen copy constructor definiere?
-
tobi007 schrieb:
warum macht der compiler ueberhaupt eine implicit type conversion wenn ich folgendes aufrufe?
Weil in C++ Konstruktoren, die mit einem Argument aufgerufen werden können und nicht
explicitsind, Konvertierungskonstruktoren darstellen. Ist nicht schön, daexplicitdie Regel und nicht die Ausnahme ist, aber die Einsicht hätte vor zwei Jahrzehnten kommen müssen.tobi007 schrieb:
gilt das nur wenn ich keinen copy constructor definiere?
Nein, das hat damit nichts zu tun. Kopierkonstruktoren werden nur in Betracht gezogen, wenn das Argument vom gleichen Typ wie die Klasse ist. Der Compiler definiert sowieso Kopierkonstruktoren, wenn er kann und du nichts angibst.
-
warum compiliert dann line 18 nicht? -> error: no matching function for call to ‘Foo::Foo(Foo)’
#include <iostream> using namespace std; class Foo { public: Foo(int x) { cout << "Foo constructor" << endl; } Foo(Foo &a) { cout << "Foo copy constructor" << endl; } }; class Bar { public: Bar(int x) { cout << "Bar constructor" << endl; } }; int main() { Foo f1(2); Foo f2 = f1; Foo f3 = 2; //<--- fails Bar b = 2; // implicit convertion return 0; }
-
Weil
Foo(Foo &a)kein richtiger Kopierkonstruktor ist*. Du brauchst eine Referenz auf const. Mit der Anweisung
Foo f3 = 2;versuchst du, ein temporäres Objekt an eine Referenz auf nicht-konstante Objekte zu binden, was nicht erlaubt ist.
Darin liegt auch ein subtiler Unterschied zwischen den Deklarationen
T var(expr);undT var = expr;. Bei letzterem darf der CompilerT var = T(expr);draus machen. Und auch wenn er es nicht macht, muss dieser Ausdruck kompilieren._______
* Diese Konstruktorsignatur wurde in C++98 als Hack eingesetzt, um Move-Konstruktoren zu emulieren. Prominentestes Beispiel dieses Idioms iststd::auto_ptr.
-
Wobei allerdings noch anzumerken ist:
Es wird zwar verlangt, dass dort ein Copyctor existiert, er wird aber nicht aufgerufen, da das wegoptimiert werden kann.
-
@nexus: oh sorry nicht gesehen

welchen konstruktorsignatur hack meinst du?
-
Nexus schrieb:
Ist nicht schön, da
explicitdie Regel und nicht die Ausnahme istWas meinst du damit?
Kopierkonstruktoren werden nur in Betracht gezogen, wenn das Argument vom gleichen Typ wie die Klasse ist.
Falsch. Kopierkonstruktoren werden genauso in die Overload-Resolution mit einbezogen wie andere Funktionen. (s. §13.3.1.4)
Edit:kein richtiger Kopierkonstruktor ist*.
Ebenfalls falsch. Es ist ein Kopierkonstruktor, jedoch kein sinnvoller.
War das zu nitpickerisch?
-
wie laesst sich folgendes erklaeren?
Foo f2 = f1; // ... ruft den copy constructor auf Foo f3 = 2; // ... ruft the constructor auf
-
ok, sollte nun klar sein.
-
@nexus du meinst ja wohl folgendes?
T y; T x = y; means T x(T(y));