我正在尝试编写一个函数来打印常见STL容器(vector,list等)的表示。我给函数一个模板参数T,例如,它可能代表向量。我在获取类型为T的迭代器时遇到问题。
vector<int> v(10, 0);
repr< vector<int> >(v);
...
template <typename T>
void repr(const T & v)
{
cout << "[";
if (!v.empty())
{
cout << ' ';
T::iterator i;
for (i = v.begin();
i != v.end()-1;
++i)
{
cout << *i << ", ";
}
cout << *(++i) << ' ';
}
cout << "]\n";
}
...
brett@brett-laptop:~/Desktop/stl$ g++ -Wall main.cpp
main.cpp: In function ‘void repr(const T&)’:
main.cpp:13: error: expected ‘;’ before ‘i’
main.cpp:14: error: ‘i’ was not declared in this scope
main.cpp: In function ‘void repr(const T&) [with T = std::vector<int, std::allocator<int> >]’:
main.cpp:33: instantiated from here
main.cpp:13: error: dependent-name ‘T::iterator’ is parsed as a non-type, but instantiation yields a type
main.cpp:13: note: say ‘typename T::iterator’ if a type is meant
我按照编译器的建议尝试了'typename T :: iterator',但只是出现了更加神秘的错误。
编辑:谢谢你的帮助!这是一个适用于任何想要使用此功能的人的工作版本:
template <typename T>
void repr(const T & v)
{
cout << "[";
if (!v.empty())
{
cout << ' ';
typename T::const_iterator i;
for (i = v.begin();
i != v.end();
++i)
{
if (i != v.begin())
{
cout << ", ";
}
cout << *i;
}
cout << ' ';
}
cout << "]\n";
}
答案 0 :(得分:18)
您需要typename
告诉编译器::iterator
应该是一个类型。编译器不知道它是一个类型,因为在实例化模板之前它不知道T是什么。例如,它还可以引用一些静态数据成员。这是你的第一个错误。
您的第二个错误是v
是对 const 的引用。因此,您必须使用::iterator
而不是::const_iterator
。你不能要求一个常量容器用于非const迭代器。
答案 1 :(得分:3)
将T::iterator i;
更改为typename T::const_iterator i;
,因为::iterator
的类型为T
且v
为const &
。
在合格的从属类型之前,您需要typename
。
如果没有typename
,则会有一个C ++解析规则,即除非导致语法错误,否则应将合格的从属名称解析为non-types
。
typename
声明后面的名称应该被视为一种类型。否则,名称将被解释为引用非类型。