Явный конструктор, принимающий несколько аргументов

Делает конструктор, имеющий несколько аргументов explicit есть (полезный) эффект?

Пример:

class A {
public:
explicit A( int b, int c ); // does explicit have any (useful) effect?
};

60

Решение

Вплоть до 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
79

Другие решения

Вы наткнетесь на это для инициализации скобки (например, в массивах)

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;
}
22

Отличные ответы @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, это может стоить сделать это при первом написании метода.

17

Вот мои пять центов на это обсуждение:

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 функция, потому что конструктор struct Bar объявлен как explicit,

4
По вопросам рекламы [email protected]