Explicit constructor taking multiple arguments

Does any (useful) effect have a constructor that has multiple explicit arguments?

Example:

 class A { public: explicit A( int b, int c ); // does explicit have any (useful) effect? }; 
+47
c ++ explicit-constructor
Aug 24 '16 at 11:29
source share
4 answers

As long as C ++ 11, yes, there is no reason to use explicit in the multi-arg constructor.

This changes in C ++ 11 due to initializer lists. Basically, copy initialization (but not direct initialization) using a list of initializers requires that the constructor not be explicit marked.

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 
+61
Aug 24 '16 at 11:35
source share

You stumbled upon it to initialize a bracket (e.g. 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; } 
+19
Aug 24 '16 at 11:34
source share

Great answers from @StoryTeller and @Sneftel are the main reason. However, IMHO, this makes sense (at least I do it), as part of a future check later changes the code. Consider your example:

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

This code does not directly use explicit .

After a while, you decide to add the default value for c so that it becomes the following:

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

In doing so, you focus on the c parameter - in retrospect, it should have a default value. You do not necessarily focus on whether A itself should be implicit. Unfortunately, this change is again explicit .

So, in order to report that ctor is explicit , he can pay for it the first time he writes a method.

+14
Aug 24 '16 at 11:40
source share

Here are my five cents for 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 the use of the initializer list along with the bar function, since the struct Bar constructor is declared as explicit .

+2
Aug 24 '16 at 12:14
source share



All Articles