cpp/language/converting constructor: Difference between revisions
m Fix |
m →Example: +maybe_unused-like crutches |
||
| Line 44: | Line 44: | ||
// B b8 = {}; // error: copy-list-initialization selected an explicit constructor | // B b8 = {}; // error: copy-list-initialization selected an explicit constructor | ||
// B::B() | // B::B() | ||
} | } | ||
}} | }} | ||
===See also=== | ===See also=== | ||
* {{rlp | copy assignment}} | * {{rlp|copy assignment}} | ||
* {{rlp | copy constructor}} | * {{rlp|copy constructor}} | ||
* {{rlp | copy elision}} | * {{rlp|copy elision}} | ||
* {{rlp | default constructor}} | * {{rlp|default constructor}} | ||
* {{rlp | destructor}} | * {{rlp|destructor}} | ||
* {{ | * {{|explicit}} | ||
* {{rlp | initialization}} | * {{rlp|initialization}} | ||
** {{rlp | aggregate initialization}} | ** {{rlp|aggregate initialization}} | ||
** {{rlp | constant initialization}} | ** {{rlp|constant initialization}} | ||
** {{rlp | copy initialization}} | ** {{rlp|copy initialization}} | ||
** {{rlp | default initialization}} | ** {{rlp|default initialization}} | ||
** {{rlp | direct initialization}} | ** {{rlp|direct initialization}} | ||
** {{rlp | initializer list}} | ** {{rlp|initializer list}} | ||
** {{rlp | list initialization}} | ** {{rlp|list initialization}} | ||
** {{rlp | reference initialization}} | ** {{rlp|reference initialization}} | ||
** {{rlp | value initialization}} | ** {{rlp|value initialization}} | ||
** {{rlp | zero initialization}} | ** {{rlp|zero initialization}} | ||
* {{rlp | move assignment}} | * {{rlp|move assignment}} | ||
* {{rlp | move constructor}} | * {{rlp|move constructor}} | ||
* {{rlp | new}} | * {{rlp|new}} | ||
deesfritjaptruzh | |||
Latest revision as of 12:09, 23 February 2023
A constructor that is not declared with the specifier explicit and which can be called with a single parameter(until C++11) is called a converting constructor.
Unlike explicit constructors, which are only considered during direct initialization (which includes explicit conversions such as static_cast), converting constructors are also considered during copy initialization, as part of user-defined conversion sequence.
It is said that a converting constructor specifies an implicit conversion from the types of its arguments (if any) to the type of its class. Note that non-explicit user-defined conversion function also specifies an implicit conversion.
Implicitly-declared and user-defined non-explicit copy constructors and move constructors are converting constructors.
Example
struct A
{
A() { } // converting constructor (since C++11)
A(int) { } // converting constructor
A(int, int) { } // converting constructor (since C++11)
};
struct B
{
explicit B() { }
explicit B(int) { }
explicit B(int, int) { }
};
int main()
{
A a1 = 1; // OK: copy-initialization selects A::A(int)
A a2(2); // OK: direct-initialization selects A::A(int)
A a3{4, 5}; // OK: direct-list-initialization selects A::A(int, int)
A a4 = {4, 5}; // OK: copy-list-initialization selects A::A(int, int)
A a5 = (A)1; // OK: explicit cast performs static_cast, direct-initialization
// B b1 = 1; // error: copy-initialization does not consider B::B(int)
B b2(2); // OK: direct-initialization selects B::B(int)
B b3{4, 5}; // OK: direct-list-initialization selects B::B(int, int)
// B b4 = {4, 5}; // error: copy-list-initialization selected an explicit constructor
// B::B(int, int)
B b5 = (B)1; // OK: explicit cast performs static_cast, direct-initialization
B b6; // OK, default-initialization
B b7{}; // OK, direct-list-initialization
// B b8 = {}; // error: copy-list-initialization selected an explicit constructor
// B::B()
[](...){}(a1, a4, a4, a5, b5); // may suppress "unused variable" warnings
}