Nein, sie sind nicht gleich. explicit
lässt implizite Konvertierungen zu diesem Typ nicht zu, wenn dieser Konstruktor ausgewählt ist - implizite Konvertierungen in Argumenten sind nicht wichtig. delete
verbietet jede Konstruktion, wenn dieser Konstruktor ausgewählt ist, und kann dazu verwendet werden, die implizite Umwandlung des Arguments zu verbieten.
So zum Beispiel:
struct X {
explicit X(int) { }
};
void foo(X) { }
foo(4); // error, because X's constructor is explicit
foo(X{3}); // ok
foo(X{'3'}); // ok, this conversion is fine
, die aus delete
ing einen Konstruktor getrennt ist:
struct Y {
Y(int) { }
Y(char) = delete;
};
void bar(Y) { }
bar(4); // ok, implicit conversion to Y since this constructor isn't explicit
bar('4'); // error, this constructor is deleted
bar(Y{'4'}); // error, doesn't matter that we're explicit
Die beiden Techniken auch orthogonal sind. Wenn Sie eine Art nicht sein wollen implizit konvertierbare und nur konstruierbar aus genau einem int
, können Sie beides:
struct W {
explicit W(int) { }
template <class T>
W(T) = delete;
};
void quux(W);
quux(4); // error, constructor is explicit
quux('4'); // error, constructor is deleted
quux(4L); // error, constructor is deleted
quux(W{'4'}); // error, constructor is deleted
quux(W{5}); // ok
Beachten Sie, dass das den expliziten Konstruktor und auch den Copy/Move-Konstruktor aufruft. 'Z z (1LL);' würde nur den expliziten Konstruktor aufrufen. – immibis