前几天,我发现这是可能的:
template <class T> struct base {};
struct derived: base<int> {};
int main()
{
// The base class template is accessible here
typename derived::base<double> x;
// from the comments, even this works
typename derived::derived::base<double>::base<int>::base<void> y;
}
我不记得曾经在cppreference或C ++教程中阅读过这篇文章,或者这是在巧妙的模板元编程技巧中被利用的(因为我确信它可以)。我有几个问题:
答案 0 :(得分:4)
正如comment中@Nir Friedman指出的那样,typename derived::derived::base<double>::base<int>::base<void> y;
可能实际上是不正确的,因为derived::derived::base<double>::base<int>::base
被视为base
的构造函数,每{{3} }}
- 这件事有特定的名字吗?
它被称为 inject-class-name 。
- C ++标准和cppreference中记录了哪些内容?
在标准中:[class.qual]/2指定将类的名称视为该类的公共成员。 [class]/2指定类模板的inject-class-name可以用作模板名称或类型名称。
关于cppreference:它在[temp.local]中记录(不完整)。
- 是否有任何模板元编程技巧利用这个?
我不知道任何这样的技巧,但在日常使用中,只要在类定义中命名当前类,就会使用inject-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
};
后者可能被故意用于缩短成员声明。
基类的inject-class-name主要用于(无意识地)在成员初始化列表中:
struct B : A<int> {
B() : A() {}
};