A using-declaration ([namespace.udecl]) that names a constructor implicitly declares a set of inheriting constructors. The candidate set of inherited constructors from the class X named in the using-declaration consists of actual constructors and notional constructors that result from the transformation of defaulted parameters as follows:
all non-template constructors of X, and
for each non-template constructor of X that has at least one parameter with a default argument, the set of constructors that results from omitting any ellipsis parameter specification and successively omitting parameters with a default argument from the end of the parameter-type-list, and
all constructor templates of X, and
for each constructor template of X that has at least one parameter with a default argument, the set of constructor templates that results from omitting any ellipsis parameter specification and successively omitting parameters with a default argument from the end of the parameter-type-list.
For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy, or move constructor for that class. Similarly, for each constructor template in the candidate set of inherited constructors, a constructor template is implicitly declared with the same constructor characteristics unless there is an equivalent user-declared constructor template ([temp.over.link]) in the complete class where the using-declaration appears. [ Note: Default arguments are not inherited. An exception-specification is implied as specified in [except.spec]. — end note ]
A constructor so declared has the same access as the corresponding constructor in X. It is deleted if the corresponding constructor in X is deleted ([dcl.fct.def]). An inheriting constructor shall not be explicitly instantiated ([temp.explicit]) or explicitly specialized ([temp.expl.spec]).
[ Note: Default and copy/move constructors may be implicitly declared as specified in [class.ctor] and [class.copy]. — end note ]
[ Example:
struct B1 { B1(int); }; struct B2 { B2(int = 13, int = 42); }; struct D1 : B1 { using B1::B1; }; struct D2 : B2 { using B2::B2; };
The candidate set of inherited constructors in D1 for B1 is
B1(const B1&)
B1(B1&&)
B1(int)
The set of constructors present in D1 is
D1(), implicitly-declared default constructor, ill-formed if odr-used
D1(const D1&), implicitly-declared copy constructor, not inherited
D1(D1&&), implicitly-declared move constructor, not inherited
D1(int), implicitly-declared inheriting constructor
The candidate set of inherited constructors in D2 for B2 is
B2(const B2&)
B2(B2&&)
B2(int = 13, int = 42)
B2(int = 13)
B2()
The set of constructors present in D2 is
D2(), implicitly-declared default constructor, not inherited
D2(const D2&), implicitly-declared copy constructor, not inherited
D2(D2&&), implicitly-declared move constructor, not inherited
D2(int, int), implicitly-declared inheriting constructor
D2(int), implicitly-declared inheriting constructor
— end example ]
[ Note: If two using-declarations declare inheriting constructors with the same signatures, the program is ill-formed ([class.mem], [over.load]), because an implicitly-declared constructor introduced by the first using-declaration is not a user-declared constructor and thus does not preclude another declaration of a constructor with the same signature by a subsequent using-declaration. [ Example:
struct B1 { B1(int); }; struct B2 { B2(int); }; struct D1 : B1, B2 { using B1::B1; using B2::B2; }; struct D2 : B1, B2 { using B1::B1; using B2::B2; D2(int); };
— end example ] — end note ]
[ Example:
struct B1 { B1(int) { } }; struct B2 { B2(double) { } }; struct D1 : B1 { using B1::B1; int x; }; void test() { D1 d(6); D1 e; } struct D2 : B2 { using B2::B2; B1 b; }; D2 f(1.0); template< class T > struct D : T { using T::T; ~D() { std::clog << "Destroying wrapper" << std::endl; } };
Class template D wraps any class and forwards all of its constructors, while writing a message to the standard log whenever an object of class D is destroyed. — end example ]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4