根据Scott Meyers的书,模板中依赖于模板参数的名称称为依赖名称。 (当依赖名称嵌套在类中时,我将其称为嵌套依赖名称)
因此必须使用" typename"依赖名称前的关键字,对吗?
template<typename C>
void print2nd(const C& container) {
typename C::const_iterator iter(container.begin());
...
}
但是为什么在这段代码中,取自Josuttis的书,std :: vector这是另一个显然依赖于T的实例化,它们不使用&#34; typename&#34;这里:
template <typename T>
class Stack {
(?typename?) std::vector<T> elems;
...
};
这一切看起来令人困惑,特别是Meyers的另一个例子:
template<typename IterT>
void workWithIterator(IterT iter) {
typename std::iterator_traits<IterT>::value_type temp(*iter);
... }
他们对我看起来都一样。你如何区分?
答案 0 :(得分:2)
在第一个示例(typename C::const_iterator
)中,编译器无法直接知道const_iterator
:例如,它可能是静态成员。这就是为什么你需要在声明前添加typename
前缀,以表明它是一种类型。
在第二个例子中,编译器知道std::vector<T>
是一种类型,即使不知道什么是T
。这就是为什么在这种情况下不需要typename
。
答案 1 :(得分:1)
当你有
时typename C::const_iterator iter(container.begin());
const_iterator
部分是一种取决于C
是什么的类型。所以你需要typename
告诉编译器C::const_iterator
是一个类型。
在
std::vector<T> elems;
您声明的std::vector
元素的类型为T
。你根本不需要typename
。即使vector
依赖于类型T
,它也不是取决于T
的名称。
您可以在Where and why do I have to put the "template" and "typename" keywords?
详细了解typename
和template
的时间和地点。