Vin*_*ent 14 c++ inheritance language-lawyer template-meta-programming c++11
前几天,我发现这是可能的:
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;
}
Run Code Online (Sandbox Code Playgroud)
我没有回忆过在cppreference或C++教程中读过这个,或者这是在聪明的模板元编程技巧中被利用的(因为我确信它可以).我有几个问题:
正如@Nir Friedman 在评论中指出的那样,typename derived::derived::base<double>::base<int>::base<void> y;实际上可能是格式错误的,因为derived::derived::base<double>::base<int>::base被视为base, 每个[class.qual]/2的构造函数。
- 这个东西有具体的名字吗?
它被称为注入类名称。
- 它在 C++ 标准和 cppreference 中的何处记录?
在标准中:[class]/2指定类的名称被视为该类的公共成员。[temp.local]指定类模板的注入类名可以用作模板名或类型名。
关于 cppreference:它(不完整)记录在http://en.cppreference.com/w/cpp/language/unqualified_lookup#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
};
Run Code Online (Sandbox Code Playgroud)
后者可能被故意用于缩短成员声明。
基类的注入类名称通常(无意识地)用于成员初始化列表:
struct B : A<int> {
B() : A() {}
};
Run Code Online (Sandbox Code Playgroud)