Во-первых, любой конструктор может быть помечен explicit
. Сколько аргументов это имеет, не имеет значения.
После этого вам просто необходимо понять, что на самом деле означает explicit
. Это просто означает, что единственный способ вызова конструктора - это когда вы явно указываете имя класса:
struct foo
{
foo(int){}
explicit foo(double){}
};
void bar(foo){}
bar(5); // okay, calls foo(int) to construct the foo
bar(3.14); // error, cannot call foo(double) because foo was not explicitly used
bar(foo(3.14)); // okay, calls foo(double) to construct the foo
Причина, по которой мы не помечаем конструкторы с несколькими аргументами явными, заключается в том, что они бесполезны. Дано:
struct baz
{
baz(int, int, int);
};
Как еще можно вызвать этот конструктор, кроме как сказать baz
? (Как в baz(1, 2, 3)
.) †
В вашем примере explicit
было бы разумно, потому что вы могли бы вызвать этот конструктор только с одним аргументом. То, что вы на самом деле делаете, зависит только от того, считаете ли вы, что оно должно быть неявно конвертируемым или нет.
† Это не относится к спискам инициализаторов C ++ 11. В C ++ 11, я думаю, вы могли бы сказать:
void qaz(baz) {}
qaz({1, 2, 3});
И мне удалось получить неявное преобразование в конструктор с несколькими аргументами, но я не знаю достаточно о списках инициализаторов, чтобы сделать содержательный комментарий, кроме как сноска.