Явный конструктор, принимающий несколько аргументов
делает конструктор, имеющий несколько аргументов explicit
есть ли (полезный) эффект?
пример:
class A {
public:
explicit A( int b, int c ); // does explicit have any (useful) effect?
};
4 ответа:
до C++11, Да, нет причин использовать
explicit
в конструкторе с несколькими аргументами.это изменяется в C++11, из-за списков инициализаторов. В принципе, для инициализации копирования (но не прямой инициализации) со списком инициализаторов требуется, чтобы конструктор не был отмечен
explicit
.пример:
struct Foo { Foo(int, int); }; struct Bar { explicit Bar(int, int); }; Foo f1(1, 1); // ok Foo f2 {1, 1}; // ok Foo f3 = {1, 1}; // ok Bar b1(1, 1); // ok Bar b2 {1, 1}; // ok Bar b3 = {1, 1}; // NOT OKAY
вы наткнетесь на него для инициализации скобки (например, в массивах)
struct A { explicit A( int b, int c ) {} }; struct B { B( int b, int c ) {} }; int main() { B b[] = {{1,2}, {3,5}}; // OK A a1[] = {A{1,2}, A{3,4}}; // OK A a2[] = {{1,2}, {3,4}}; // Error return 0; }
отличные ответы от @StoryTeller и @Sneftel являются основной причиной. Тем не менее, ИМХО, это имеет смысл (по крайней мере, я это делаю), как часть будущих проверок более поздних изменений в коде. Рассмотрим ваш пример:
class A { public: explicit A( int b, int c ); };
этот код напрямую не выигрывает от
explicit
.некоторое время спустя, вы решили добавить значение по умолчанию для
c
, так получается вот что:class A { public: A( int b, int c=0 ); };
делая это, вы фокусируетесь на
c
параметр-в ретроспективе, это должен иметь значение по умолчанию. Вы не обязательно фокусируетесь на ЛиA
само должно быть неявно построено. К сожалению, это изменение делаетexplicit
снова актуальна.Итак, чтобы передать, что ctor-это
explicit
, это может стоить сделать это при первом написании метода.
вот мои пять копеек в эту дискуссию:
struct Foo { Foo(int, double) {} }; struct Bar { explicit Bar(int, double) {} }; void foo(const Foo&) {} void bar(const Bar&) {} int main(int argc, char * argv[]) { foo({ 42, 42.42 }); // valid bar({ 42, 42.42 }); // invalid return 0; }
как вы можете легко увидеть,
explicit
запрещает использовать список инициализаторов вместе сbar
функция bacause конструкторstruct Bar
объявленexplicit
.