当模板类继承自另一个模板类时,必须再次重新定义基类中的typedef(即它们不会自动继承),并且需要限定基类中的函数调用。这是为什么?这不是明确的吗?
因此,如果我有20个模板类,都定义了相同的typedef,我无法引入包含这些定义的基类并继承它,因为我必须在每个类中重新定义typedef,这会使目的。这使源代码变得不必要地冗长。
我可以看到这已在question中讨论,但我不理解评论
C ++名称查找规则指定仅在模板化基类中搜索名称(如果它取决于模板参数(如果它是“依赖名称”))。如果名称不依赖于模板参数,则不会在那里搜索。
这是什么原因?这对我没用。
或许,以下代码段会更好地说明我的问题:
#include <iostream>
template <unsigned N, typename T>
struct A
{
typedef T U;
static void foo(T x) { std::cout << N + x << "\n"; }
};
template <unsigned N, typename T>
struct B : public A<N, T>
{
// Why do I have to redeclare U? Isn't is unambiguous already?
typedef typename A<N, T>::U U;
// why do I have to specify B::? Isn't it unambiguous already?
static void zoo(U x) { B::foo(x); }
};
int main()
{
B<2,int>().zoo(3);
B<2,double>().zoo(3.5);
return 0;
}
答案 0 :(得分:3)
由于两阶段查找而发生了这种情况。引自here:
- 模板定义时间:最初解析模板时,在实例化之前,编译器会解析模板并 查找任何&#34;非依赖&#34;名。名字是&#34;非依赖&#34;如果 名称查找的结果不依赖于任何模板参数,和 因此,从一个模板实例化到另一个模板实例化将是相同的。
- 模板实例化时间:当模板实例化时,编译器会查找任何依赖的&#34;名字,现在它已经完整 用于执行查找的模板参数。这个查找的结果 可以(并经常做!)从一个模板实例化到另一个模板实例化。
醇>
因此,在初始解析期间,编译器认为U
是非依赖名称并尝试查找它并且它无法找到任何内容,因为它不允许查看依赖基类。但是如果U
是依赖名称,那么编译器会在实例化阶段查找它并在基类中找到它。
答案 1 :(得分:1)
根本原因是课程可以专业化:
template<class T>
struct A {};
template<class T>
struct B : A<T> {
typedef typename A<T>::referent target;
void niceName() {A<T>::uglyName();}
};
template<class T>
struct A<T*> {
typedef T referent;
void uglyName();
};
B<int*>::target i; // OK: int
当然,相反的情况(主要模板定义有用的东西,我们只是担心专业化可能会改变或删除它们)更常见,这使得规则似乎是任意的。 / p>