While reading this question, I found a strange point:
template <typename T>
class Subclass : public Baseclass<T>
{
public:
using typename Baseclass<T>::Baseclass;
// ^^^^^^^^
};
Since typename, Baseclass<T>::Baseclass should be injected class name, not a constructor. As far as I know, it's the same case as this:
template <typename T>
class Base
{
public:
typedef short some_type;
};
template <typename T>
class Sub : public Base<T>
{
public:
using typename Base<T>::some_type;
};
To make sure, I wrote a test code.
#include <iostream>
template <typename T>
class Base
{
public:
Base() { std::cout << "A::A()\n"; }
Base(int) { std::cout << "A::A(int)\n"; }
Base(const char *) { std::cout << "A::A(const char *)\n"; }
};
template <typename T>
class Sub : public Base<T>
{
using typename Base<T>::Base;
};
int main()
{
Sub<char> s1;
Sub<char> s2(3);
Sub<char> s3("asdf");
}
However, it runs on gcc 4.8.3.
$ g++ -std=c++1y -Wall -Wextra -Werror -pedantic test.cpp -o test && ./test
A::A()
A::A(int)
A::A(const char *)
It also runs without typename.
$ cat test.cpp
...
using Base<T>::Base;
...
$ g++ -std=c++1y -Wall -Wextra -Werror -pedantic test.cpp -o test && ./test
A::A()
A::A(int)
A::A(const char *)
Why did I get these results? What did I miss?
The standard is pretty clear about this ([namespace.udecl]/1)
The
typenamekeyword is therefore an optional part of a using declaration that may appear even for using declarations of non-types. The following code should therefore be standard conformant:Both
SubNoTypenameandSubTypenameare recognized as standard conformant by gcc. On the other hand clang++ complains inSubTypenameabout malplacedtypenamekeywords. However, this is not even consistent, because it should then complain about a missingtypenameinusing Base< T >::Ttype;. This clearly is a clang bug.Edit The
typenamekeyword is also allowed if the base class is no template class, a place where ordinarily you would never expect this keyword to be valid: