简短回答:每次引用的嵌套名称是从属名称,即嵌套在具有未知参数的模板实例中。
长答案:C++中有三层实体:值,类型和模板。所有这些都可以有名称,并且名称本身并不会告诉你它是哪一层实体。相反,关于名称实体性质的信息必须从上下文中推断出来。
每当这个推断是不可能的,你必须指定它:
template <typename> struct Magic; // defined somewhere else
template <typename T> struct A
{
static const int value = Magic<T>::gnarl; // assumed "value"
typedef typename Magic<T>::brugh my_type; // decreed "type"
// ^^^^^^^^
void foo() {
Magic<T>::template kwpq<T>(1, 'a', .5); // decreed "template"
// ^^^^^^^^
}
};
这里的名字Magic<T>::gnarl
,Magic<T>::brugh
和Magic<T>::kwpq
不得不被expliciated,因为它是不可能告诉:由于Magic
是一个模板时,非常性质类型Magic<T>
取决于T
- 例如,可能存在与主模板完全不同的专业化。
什么令Magic<T>::gnarl
成为独立名称是因为我们在模板定义中,其中T
未知。如果我们使用了Magic<int>
,这将是不同的,因为编译器知道(你保证!)Magic<int>
的完整定义。如果你想自己测试一下,你可以使用Magic
的一个示例定义,为了简洁起见,请特别注意在专门化中使用constexpr
;如果你有一个老的编译器,可以随意更改静态成员常量声明旧式预C++ 11形式)
template <typename T> struct Magic
{
static const T gnarl;
typedef T & brugh;
template <typename S> static void kwpq(int, char, double) { T x; }
};
template <> struct Magic<signed char>
{
// note that `gnarl` is absent
static constexpr long double brugh = 0.25; // `brugh` is now a value
template <typename S> static int kwpq(int a, int b) { return a + b; }
};
用法:
int main()
{
A<int> a;
a.foo();
return Magic<signed char>::kwpq<float>(2, 3); // no disambiguation here!
}
http://stackoverflow.com/questions/610245/where-and-why-do-我必须把模板和类型名称的依赖名称 –