質問: vec.begin(); }` ``` この例で「typename」キーワードが必要な理由は何ですか? 「typename」を指定する必要がある場合は他にもありますか?
回答: 短い答え:名前が*従属名*のネストされた名前を参照するときはいつでも、パラメータが未知のテンプレートインスタンスの中に入れ子になっています。 長い答え:C ++には、値、型、テンプレートという3つのエンティティがあります。それらのすべてが名前を持つことができます。名前だけではエンティティのどの階層であるかは分かりません。むしろ、名前の実体の性質に関する情報は、文脈から推論されなければならない。 この推論が不可能なときはいつでも、それを指定する必要があります: ``` template struct Magic;//defined somewhere else template struct A { static const int value = Magic::gnarl;//assumed "value" typedef typename Magic::brugh my_type;//decreed "type" // ^^^^^^^^ void foo() { Magic::template kwpq(1, 'a', .5);//decreed "template" // ^^^^^^^^ } }; ``` Here the names `Magic::gnarl`, `Magic::brugh` and `Magic::kwpq` had to be expliciated, because it is impossible to tell: Since `Magic` is a template, the very *nature* of the type `Magic` depends on `T` -- there may be specializations which are entirely different from the primary template, for example. What makes `Magic::gnarl` a dependent name is the fact that we're inside a template definition, where `T` is unknown. Had we used `Magic`, this would be different, since the compiler knows (you promise!) the full definition of `Magic`. (これを自分でテストしたい場合は、使用できる `Magic` のサンプル定義を次に示します。簡潔にするためにspecializeで `constexpr` を使用してください。コンパイラは、静的メンバ定数の宣言を古いスタイルのpre-C ++ 11フォームに自由に変更することができます。) ``` template struct Magic { static const T gnarl; typedef T & brugh; template static void kwpq(int, char, double) { T x; } }; template <> struct Magic { //note that `gnarl` is absent static constexpr long double brugh = 0.25; //`brugh` is now a value template static int kwpq(int a, int b) { return a + b; } }; ``` 使用法: ``` int main() { A a; a.foo(); return Magic::kwpq(2, 3); //no disambiguation here! } ```