No, they're not the same. explicit
disallows implicit conversions to that type if that constructor is selected - implicit conversions in arguments don't matter. delete
disallows any construction if that constructor is selected, and can be used to disallow implicit argument conversion.
So for instance:
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
That is separate from delete
ing a constructor:
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
The two techniques are also orthogonal. If you want a type to not be implicitly-convertible and only constructible from exactly an int
, you can do both:
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