Ответ 1
Как отметил @Nir Friedman в comment, typename derived::derived::base<double>::base<int>::base<void> y;
может быть плохо сформирован, потому что derived::derived::base<double>::base<int>::base
рассматривается как конструктор base
, per [class.qual]/2.
- У этой вещи есть определенное имя?
Он называется injected-class-name.
- Где он задокументирован в стандарте С++ и на cppreference?
В стандарте: [class]/2 указывает, что имя класса рассматривается так, как если бы он был публичным членом этого класс. [temp.local] указывает, что имя класса с добавленным именем шаблона класса может использоваться как имя шаблона, имя.
В cppreference: он (не полностью) задокументирован в http://en.cppreference.com/w/cpp/language/unqualified_lookup#Injected_class_name.
- Есть ли какой-либо шаблонный метапрограммирующий трюк, использующий это?
Я не знаю о таких трюках, хотя в повседневном использовании имя injected-class-name используется всякий раз, когда текущий класс указан в определении класса:
template<class T>
struct A {
A<T>& operator=(const A<T>&); // injected-class-name as template-name
A& operator=(A&&); // injected-class-name as type-name
};
Последнее может быть намеренно использовано для сокращения объявления участника.
Введенное имя класса базового класса в основном используется (бессознательно) в списке инициализаторов:
struct B : A<int> {
B() : A() {}
};