Here is class foo:
template <typename T>
struct foo
{
foo()
{
t = nullptr;
}
foo(T* p, bool flag)
{
t = p;
}
private:
T* t;
};
Here is class bar:
template <typename T>
struct bar: public foo<T>
{
using foo<T>::foo<T>;
};
Is it correct syntax for inheriting constructors? If I use "using foo::foo;" then compiler of Visual C++ 2010 dies. So basically how to inherit constructors from template classes in VC++ 2010?
To let this parse correctly, you would need to insert
template
before thefoo<T>;
, to tell the compiler thatfoo
is to be regarded as a template name (it cannot look intofoo<T>
to tell itself, sinceT
is unknown). But using::template
is not allowed in a using declaration. The name also does not refer to all constructors ofbar
: Instead, it would refer to a specific constructor function template specialization (T
is the template argument) of such a constructor as followsIn addition, it's not valid for a using declaration to use a
template-id
(likefoo<T>
) as its name (which in effect forbids it to refer to function template specialization, with the addition of forbidding to name conversion function template specializations stated too), so even if you correct the parsing problem using::template
(if it would be possible), you would still error out at this point.When inherited constructors were introduced, special rules were added that allow to reference a constructor using a syntactic rule: If you have a qualified-id (which basically a qualified name using
...::...
), and the last qualified before the final part names a specific class, then you can denote the constructor(s) of that class in two additional ways:foo<T>
) and the final part matches the template name (so,foo<T>::foo
orTTP<T>::TTP
withTTP
being a template template parameter).foo::foo
orT::T
, withT
being a template parameter).These two additional rules are only active in a using declaration. And they were naturally not present in C++03. The other rule that was also present in C++03 is: If the final part names the injected class name, then this qualified name also refers to the constructor:
foo::foo
would therefor work. But with this rule alone,T::T
(whereT
denotes classfoo
) would not work, becausefoo
has no member calledT
.Therefor, with the special rules in place you can write
The second is valid too:
foo
is the injected class name which was injected into the base classfoo<T>
and inherited tobar
. We refer to that name bybar::foo
, and then add the last partfoo
, which refers to the injected class name again, to denote the constructor(s) of `foo.Now you understand why the initial name you tried would refer to a constructor function template specialization (if it were to be allowed to): Because the
foo<T>::foo
part would name all constructors, and the<T>
that would follow would then filter out the template and pass the type argument.