短い答え:という従属名のネストされた名前を参照するときはいつでも、パラメータが未知のテンプレートインスタンスの中に入れ子になっています。
長い答え:C++には、値、型、テンプレートという3つのエンティティがあります。それらのすべてが名前を持つことができます。名前だけではエンティティのどの階層であるかは分かりません。むしろ、名前の実体の性質に関する情報は、文脈から推論されなければならない。
この推論が不可能なときはいつでも、あなたはそれを指定する必要があります。
ここ
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
がテンプレートであるので、非常にのタイプのはT
に依存しています。たとえば、1次テンプレートとはまったく異なる特殊化があるかもしれません。
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- i-have-to-put-template-and-typ-name-on-dependent-names –