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

Pet*_* G. 77 c++ explicit-constructor

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

例:

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

Sne*_*tel 104

直到C++ 11,是的,没有理由explicit在多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
Run Code Online (Sandbox Code Playgroud)

  • 我认为使用“我为什么要那个”或“什么时候有用”的解释会更好。 (2认同)

Sto*_*ica 28

你偶然发现了大括号初始化(例如在数组中)

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;
}
Run Code Online (Sandbox Code Playgroud)


Ami*_*ory 23

@StoryTeller和@Sneftel的优秀答案是主要原因.但是,恕我直言,这是有意义的(至少我这样做),作为未来验证的一部分,以后会改变代码.考虑你的例子:

class A {
    public:
        explicit A( int b, int c ); 
};
Run Code Online (Sandbox Code Playgroud)

此代码不直接受益explicit.

一段时间后,您决定为其添加默认值c,因此它变为:

class A {
    public:
        A( int b, int c=0 ); 
};
Run Code Online (Sandbox Code Playgroud)

这样做时,你会专注于c参数 - 回想起来,它应该有一个默认值.你不一定关注A自己是否应该隐式构建.不幸的是,这种变化explicit再次相关.

因此,为了表达一个ctor explicit,在第一次编写方法时可能会付出代价.


Edg*_*jān 6

这是我讨论的五美分:

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;
}
Run Code Online (Sandbox Code Playgroud)

您可以很容易地看到,explicit阻止使用初始化列表和bar函数,因为构造函数struct Bar被声明为explicit.