Explicit constructor taking multiple arguments

半世苍凉 提交于 2019-12-03 02:59:54

问题


Does making a constructor having multiple arguments explicit have any (useful) effect?

Example:

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

回答1:


Up until C++11, yeah, no reason to use explicit on a multi-arg constructor.

That changes in C++11, because of initializer lists. Basically, copy-initialization (but not direct initialization) with an initializer list requires that the constructor not be marked explicit.

Example:

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



回答2:


You'd stumble upon it for brace initialization (for instance in arrays)

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;
}



回答3:


The excellent answers by @StoryTeller and @Sneftel are the main reason. However, IMHO, this makes sense (at least I do it), as part of future proofing later changes to the code. Consider your example:

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

This code doesn't directly benefit from explicit.

Some time later, you decide to add a default value for c, so it becomes this:

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

When doing this, you're focussing on the c parameter - in retrospect, it should have a default value. You're not necessarily focussing on whether A itself should be implicitly constructed. Unfortunately, this change makes explicit relevant again.

So, in order to convey that a ctor is explicit, it might pay to do so when first writing the method.




回答4:


Here's my five cents to this discussion:

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;
}

As you can easily see, explicit prevents from using initializer list alongside with bar function bacause the constructor of struct Bar is declared as explicit.



来源:https://stackoverflow.com/questions/39122101/explicit-constructor-taking-multiple-arguments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!