使构造函数具有多个参数explicit
是否有任何(有用的)效果?
例:
class A {
public:
explicit A( int b, int c ); // does explicit have any (useful) effect?
};
Answers:
直到C ++ 11,是的,没有理由explicit
在multi-arg构造函数上使用。
由于初始化列表,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
explicit
。我个人不会打扰到multi-arg构造函数explicit
。
您会偶然发现它以进行大括号初始化(例如在数组中)
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
,在首次编写该方法时可能需要这样做。
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
声明为explicit
。