Ответ 1
Ваш код является законным.
Из стандарта С++ 11, раздел 14.6.1:
Подобно обычным (не шаблонным) классам, шаблоны классов имеют имя с введенным классом (раздел 9). Имя введенного класса может использоваться как имя-шаблона или имя типа. Когда он используется с шаблоном-аргументом-списком, в качестве аргумента-шаблона для шаблона-шаблона шаблона или в качестве окончательного идентификатора в специфицированном типе-спецификаторе объявления класса класса друга, относится к самому шаблону класса.
Похоже, что ваша версия clang
все еще реализует старое правило. Исходя из ваших дополнительных комментариев, это может быть сделано только в списке инициализаторов ctor.
Пользователь Дэвид Родригес - dribeas предоставил обходной путь для компиляторов, которые не полностью реализовали правило С++ 11 с введенным классом. Используйте любое имя класса, который не является неквалифицированным, например:
derived()
: base< ::derived, T >()
// ^^ qualified with global namespace
{ }
Некоторые компиляторы могут также требовать этого в списке наследования:
template <class T>
struct derived : public base< ::derived, T >
// ^^