:-)
おかげで、次の点を考慮してください
ここ
template <typename T> void IterateOverContainer(T container) {
/* Error! */
T::iterator itr(container.begin());
}
、iterator
はT
の内部にネストタイプです。例えば、std::vector<int>::iterator
です。ここではあいまいさを避けるために、typename
キーワードが必要になる:
template <typename T> void IterateOverContainer(T container) {
/* Now good! */
typename T::iterator itr(container.begin());
}
は今、これは「明確に」タイプの名前が(それは何typename
手段だ!)され、我々はコールではなく、変数を宣言したいこと、それは明らかですので、機能。
template <typename T> void IterateOverContainer(T container) {
auto itr(container.begin());
}
あるいは、より明確に:
あなたの質問にとして今
template <typename T> void IterateOverContainer(T container) {
auto itr = container.begin();
}
、:どのように新しいC++ 11個の機能で、あなたはauto
で完全にこれを回避することができ、言っ
T::x(y)
は変数を宣言できますか?
template <typename T> void IterateOverContainer(T container) {
/* Error! */
T::iterator(itr);
}
:私たちはこのような何かを持っていた場合
int (x);
そう
int x;
と同じです:まあ、原因Cの奇妙な癖に、これは完全に合法変数の宣言であります
これは、タイプT::iterator
のitr
という名前の変数の宣言として、またはT::iterator
を呼び出してitr
を呼び出すと解釈できますパラメータ。 typename
を使用すると、どちらが曖昧なのかが明確になります。
興味深いことに、この余分な括弧は、Most Vexing Parseが存在するのと同じ理由です。あなたは決してそれに遭遇しないことを願っています:-)
これは役に立ちます。
あなたのアカウントはこの質問に答えるように見えます:) –
もう少し簡単な質問です。別のクラス(Yの中のx)を定義すると、Y :: xという型ですか?私は、小文字のxは私を捨てたものだと思う、それはそれが何であれ、それがネストされたクラスであるとは気付かなかった。 T :: iterator itr(container.begin())も同様です。タイプを構築する場合は、それ以外にどのように解釈することができますか?トピックについての私の無知のためにうそをついてください。 – rubixibuc
@ rubixibuc-(私はこのメッセージを受け取る前に私の回答を少し更新しましたので、私の編集の最後を読んでみたいです)。私はあなたが "タイプを構築する"という意味を得ているのかどうかはわかりません。あなたは明確にすることができますか? – templatetypedef