В следующих случаях имя внедренного класса рассматривается как имя шаблона самого шаблона класса:
- за ним следует ‹
- он используется в качестве аргумента шаблона, который соответствует параметру шаблона шаблона
- это последний идентификатор в разработанном спецификаторе класса объявления шаблона дружественного класса.
Поэтому я попытался рассмотреть все 3 случая (дополнительно в контексте неоднозначности базы, хотя я думаю, что здесь это не должно иметь значения).
Первый случай кажется простым.
Вопрос - почему не работают закомментированные примеры? Их нет ни в GCC, ни в Clang, поэтому я не думаю, что это проблема реализации.
template <template <class> class> struct A;
template <class T> struct Base {};
template <class T> struct Derived: Base<int>, Base<char>
{
// #1
typename Derived::Base<double> d;
// #2
// using a = A<Base>;
using a = A<Derived::template Base>;
// #3
template<class U1>
friend struct Base;
// template<class U>
// friend struct Derived::template Base;
};
Являются ли приведенные выше правила только для самого шаблона, а не для баз? Если да, то каковы правила для баз, особенно для последних двух случаев?