显式构造函数采用多个参数

使explicit多个参数构造函数有任何(有用的)效果?

例:

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

直到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的出色答案。 然而,恕我直言,这是有道理的(至less我这样做),作为未来打样的一部分后来更改的代码。 考虑你的例子:

 class A { public: explicit A( int b, int c ); }; 

这个代码不直接从explicit获益。

一段时间后,你决定为c添加一个默认值,所以它变成这样:

 class A { public: A( int b, int c=0 ); }; 

当这样做的时候,你关注的是c参数 – 回想起来,它应该有一个默认值。 你不一定关注A本身是否应该被隐式构造。 不幸的是,这一变化再次使得explicit相关。

所以,为了传达一个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函数,因为struct Bar的构造struct Bar被声明为explicit