簡短回答:每次引用的嵌套名稱是從屬名稱,即嵌套在具有未知參數的模板實例中。
長答案: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-我必須把模板和類型名稱的依賴名稱 –