首先请注意,如果在这里引用template argument dependent name 之类的vector<T>::iterator,则需要将typename 放在前面。此外,取决于T 是什么,只有在std::cout 的operator<< 接受这个T 时才会编译。例如,这编译得很好:
#include <iostream>
#include <vector>
template <typename T>
void showset(std::vector<T> v)
{
for (typename std::vector<T>::iterator it = v.begin(); it != v.end(); it++)
{
std::cout << *it;
}
std::cout << std::endl;
}
struct foo
{
};
int main()
{
showset(std::vector<int>{1,2,3});
//showset(std::vector<foo>{}); // Error: `cout` doesn't take `foo`s.
return 0;
}
使用C++11的auto-enhanced语法,showset()可以这样写,然后typename就没用了:)
template <typename T>
void showset(std::vector<T> v)
{
for (auto it = v.begin(); it != v.end(); it++)
{
std::cout << *it;
}
std::cout << std::endl;
}
同样从 C++11 开始,您可以使用 range-based for loop 来实现与原始 sn-p 相同的功能:
template <typename T>
void showset(std::vector<T> v)
{
for (auto& ref : v)
{
std::cout << ref;
}
std::cout << std::endl;
}
与 lase 版本一样,因为您在这里指的不是 iterator 类型,所以没有什么可以放入 typename 的。
请注意,在这两个版本中,您都使用参数v 的值。因此,您要为每个函数调用复制整个向量。由于问题中给出了代码,因此似乎没有理由这样做,因此您应该通过引用传递它,并将其设置为 const 一个,因为您没有在 @987654342 内的任何地方修改 v @:
void showset(const std::vector<T>& v);
然后在非基于范围的for循环版本中不要忘记相应地更改循环语句:
for (typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); it++)