使用VS2017和代码:
template <typename T>
void showset(vector<T> v)
{
for (vector<T>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it;
}
cout << endl;
}
错误是:
错误C2760:语法错误:意外令牌,应为';'
问题是如何使用模板的迭代器
答案 0 :(得分:4)
首先请注意,如果在此处引用vector<T>::iterator
之类的template argument dependent name,则需要将typename
放在前面。此外,取决于T
是什么,只有在std::cout
的{{1}}接受此operator<<
的情况下,这才会编译。例如,这可以正常编译:
T
使用C ++ 11的auto
增强语法,可以像这样写#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;
}
,然后showset()
没用:)
typename
从C ++ 11开始,您还可以使用range-based for loop来实现与原始代码段相同的功能:
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;
}
与租用版本一样,因为您在这里不是指template <typename T>
void showset(std::vector<T> v)
{
for (auto& ref : v)
{
std::cout << ref;
}
std::cout << std::endl;
}
类型,所以没有iterator
的含义。
请注意,在两个版本中,您都按值使用参数typename
。因此,您要为每个函数调用复制整个向量。正如问题中给出的代码一样,似乎没有理由这样做,因此您应该通过引用传递它,并使其也成为v
,因为您不会在任何地方修改const
v
内:
showset()
,然后在非基于范围的for循环版本中,不要忘记相应地更改循环语句:
void showset(const std::vector<T>& v);
答案 1 :(得分:2)
对此的很好的建议如下:
template <typename T>
void showset(const T& v)
{
for (auto const &x : v)
{
cout << x;
}
cout << endl;
}
或者没有范围循环:
template <typename T>
void showset(const T& v)
{
for (auto it = std::begin(v); it != std::end(v); ++it)
{
cout << *it;
}
cout << endl;
}
template<typename T>
class LogContainerHelper {
LogContainerHelper(const T& v
size_t maxFront,
size_t maxTail)
: mContainer{ v }
, mMaxFront{ maxFront }
, mMaxTail{ maxTail }
{}
std::ostream &printTo(std::ostream &out) const {
// here I usually have something more complex
// depending on mMaxFront and mMaxTail values,
// don't have time to recreate that now
auto it = std::begin(mContainer);
auto end = std::end(mContainer);
out << '[';
if (it != end) {
out << *it;
++it;
}
for (; it != end; ++it)
{
out << ", " << *it;
}
return out << ']';
}
private:
const T &mContainer;
size_t mMaxFront;
size_t mMaxTail;
};
template<typename T>
std::ostream &operator <<(std::ostream &out, const LogContainerHelper<T> &helper) {
return helper.printTo(out);
}
template<typename T>
auto LogContainer(const T& v,
size_t maxFront = std::numeric_limits<size_t>::max(),
size_t maxTail = 0)
-> LogContainerHelper<T> {
return LogContainerHelper<T>{ v, maxFront, maxTail };
}
所以以后我可以这样做:
cout << "Main containter is: " << LogContainer(v) << '\n';