Нет, они не одинаковы. explicit
запрещает неявные преобразования в этот тип, если выбран этот конструктор — неявные преобразования в аргументах не имеют значения. delete
запрещает любую конструкцию, если выбран этот конструктор, и может использоваться для запрета неявного преобразования аргумента.
Так, например:
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
Это отдельно от delete
ing конструктора:
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
Эти два метода также ортогональны. Если вы хотите, чтобы тип не был неявно-преобразуемым и конструировался только точно из int
, вы можете сделать и то, и другое:
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
person
Barry
schedule
19.04.2016