当一个模板类继承另一个模板类时,基类中的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;
}
这是由于两阶段查找而发生的。引用自here:
- 模板定义时间:当模板最初被解析时,早在实例化之前,编译器就解析了模板并
查找任何“非依赖”名称。如果名称是“非依赖的”
名称查找的结果不依赖于任何模板参数,并且
因此,从一个模板实例化到另一个模板实例化将是相同的。
- 模板实例化时间:实例化模板时,编译器会查找任何“依赖”名称,因为它已具有完整的集
执行查找的模板参数。这次查找的结果
一个模板实例化与另一个模板实例化之间可能(而且经常如此!)有所不同。
因此,在初始解析期间,编译器认为U
是非依赖名称并尝试查找它,但找不到任何内容,因为不允许查看依赖基类。但如果U
是依赖名称,那么编译器将在实例化阶段查找它并在基类中找到它。
顺便说一句:VS 很容易编译它,但他们最近增加了两阶段查找的可能性。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)