In C++0x, you can use the using
keyword to inherit constructors, like so:
class B { B(int) {} };
class A : public B { using B::B; };
Yes, it appears it does, from the standard (Feb 2011 Draft), section 12.9:
template< class T >
struct D : T {
using T::T; // declares all constructors from class 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
Another thing to note, while the standard allows it, according to this list, only 1 compiler, IBM XLC++, supports this feature in a release version. GCC only currently supports it with a patch.
Edit: AJG85 pointed out that the T in the template always refers to the placeholder, so the 'using T::T' always refers to the template argument.
Yes it works, and the reason is the name lookup mechanism. The mechanism a inheriting-constructors declaration works is simple: If the using declaration's name refers to base class constructors, that's an inheriting constructors declaration. At 3.4.3.1[class.qual]p2 we find:
In a lookup in which the constructor is an acceptable lookup result and the nested-name-specifier nominates a class C
- if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C (Clause 9), or
- in a using-declaration (7.3.3) that is a member-declaration, if the name specified after the nested-name-specifier is the same as the identifier or the simple-template-id's template-name in the last component of the nested-name-specifier
the name is instead considered to name the constructor of class C.
This is the paragraph that makes out of class constructor definitions work, and this is also the paragraph that makes inheriting constructor declarations work. The second bullet applies in this case:
struct B {
B(int) { }
};
typedef B mytype;
struct A : B {
// "name ... is the same as the identifier ... in the last component ..."
using mytype::mytype;
};
template<typename T> using same = T;
struct C : B {
// "name ... is the same as the template-name ... in the last component ..."
same<B>::same;
};
The latter example proves also useful in cases such as the following
template<template<typename> class Base>
struct X : Base<int> {
using Base<int>::Base;
};
In summary:
The first bullet above is a semantic rule - if the name after the nested name specifier refers to the injected class name (B::B
or mytype::B
), then it will be translated to refer to the constructor(s).
The second bullet is a syntactic rule - the names just must match - their meaning is irrelevant otherwise - there could have been a member called Base
in the template argument provided to X
, such as in the following, but the using declaration would still import the constructors and do not name the member Base
:
template<typename T> struct D { private: T Base; };
X<D> x; // valid, the private member is *not* touched!