作为热身到我的完整的答案,考虑以下因素:
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
手段!),所以很明显,我们要声明一个变量,而不是通话一个函数。
这就是说,新的C++ 11层的功能,你可以用auto
完全回避这个问题:
template <typename T> void IterateOverContainer(T container) {
auto itr(container.begin());
}
,或者更明确:
template <typename T> void IterateOverContainer(T container) {
auto itr = container.begin();
}
现在,你的问题:如何可以T::x(y)
曾经声明一个变量?好了,由于到C的一个奇怪的怪癖,这是一个完全合法的变量声明:
int (x);
这是一样
int x;
因此,如果我们有这样的事情:
template <typename T> void IterateOverContainer(T container) {
/* Error! */
T::iterator(itr);
}
这可以解释为T::iterator
类型的名为itr
的变量的声明,或者作为对函数T::iterator
的呼叫通过itr
a是一个参数。 typename
的使用消除了它是哪一个。
有趣的是,这个额外括号的规定与Most Vexing Parse存在的原因相同。我希望你永远不会遇到它。 :-)
希望这有助于!
看起来像你的帐户是为了回答这个问题:) – 2012-02-03 03:50:37
只是几个简单的问题,如果我在另一个内部定义一个类(x内部的Y)这将是类型Y :: x?我认为小写字母x是把我扔掉的东西,我没有意识到这是一个嵌套类,如果它是什么。也是T :: iterator itr(container.begin()); 构建一个类型,如何解释? Sry因为我对这个话题的无知 – rubixibuc 2012-02-03 03:53:00
@ rubixibuc-(请注意,在我收到这条消息之前,我已经更新了我的答案,所以你可能想阅读结束我的编辑)。我不确定我是否通过“构建一个类型”来获得你的意思。你能澄清吗? – templatetypedef 2012-02-03 03:54:44