显式构造函数采用多个参数
使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
。