Assuming we have something like:
class U {
...
}
and:
class T {
T(const U&) { ... }
}
Now I can declare a variable like so:
U foo;
then T blah(foo);
or T blah = foo
Personally I prefer the later.
Now, should I change the T copy constructor to:
class T {
explicit T(const U&) { ... }
}
I can only declare a variable like:
T blah(foo);
T blah = foo;
will give me a compilation error about the impossibility to convert U to T.
http://en.cppreference.com/w/cpp/language/explicit explains that behaviour with: "Specifies constructors and (since C++11) conversion operators that don't allow implicit conversions or copy-initialization."
Now, the folks I work for require that all our constructors are made explicit. Being an old fart, I don't like changing my coding style too much and forget about T blah = ... style.
The question as such is this: "Is there a way to make a constructor explicit while allowing copy-initialization syntax?"
There are very good reasons to make a constructor explicit, and most of the time, you do want to make it explicit.
Under those instances, I thought I could do something along the line of:
class T {
template<typename = V>
T(const V&) = delete;
T(const U&) { ... }
}
Which would be a catch-all constructor forbidding all conversion but the one I actually want.
Was wondering if there was some trick I could use.
Thanks
Edit: corrected the typo as pointed by Matt McNabb answer. thanks
Answered on 23-12-2021. A conversion constructor is a single-parameter constructor that is declared without the function specifier explicit . The compiler uses conversion constructors to convert objects from the type of the first parameter to the type of the conversion constructor's class. 0.
implicit constructor is a term commonly used to talk about two different concepts in the language, the. implicitly declared constructor which is a default or copy constructor that will be declared for all user classes if no user defined constructor is provided (default) or no copy constructor is provided (copy).
In C++, if a class has a constructor which can be called with a single argument, then this constructor becomes conversion constructor because such a constructor allows automatic conversion to the class being constructed. Example.
Copy Constructor in C++ A copy constructor is a member function that initializes an object using another object of the same class. In simple terms, a constructor which creates an object by initializing it with an object of the same class, which has been created previously is known as a copy constructor.
T blah = U();
gives the error because, as you correctly explain, copy-initialization calls for implicit conversion of U
to T
; but you have marked the constructor explicit
. (Note: this is not a copy constructor)
Explicit conversion would look like T blah = T(U());
and this should work with no errors.
T blah(U());
is a function declaration (look up most vexing parse). You probably didn't actually try to use blah
as if it were an object, in your test case, otherwise you would have noticed this problem.
Moving onto your question:
Is there a way to make a constructor explicit while allowing copy-initialization syntax?
There is not, as explained by the exact text you quoted about explicit
:
Specifies constructors [...] that don't allow [...] copy-initialization.
You'll have to switch to direct or braced initialization. IMHO that's a good thing anyway, copy-initialization is cumbersome and only good for avoiding MVPs; but now that we can avoid MVPs using braced initialization, it's no longer necessary at all.
You could use either of the following, which work because in all cases a T
is directly and explicitly initialized by the list element:
T blah{ U() };
T blah = T{ U() }; // redundant copy/move operation, probably elided
Note that T blah = { U() };
cannot be used here because that form of initialization (known as copy-list-initialization) cannot use an explicit constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With