学习标准模板库时
/*
Aim:Create a vector of integers. Copy it into a list, reversing as you
do so.
*/
#include<iostream>
#include<vector>
#include<algorithm>
#include<list>
using namespace std;
template<typename t>
void print(vector <t> &v) //what changes need to be done here?
{
for (auto it = v.begin(); it < v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
print(v);
list<int> l(v.size());
reverse_copy(v.begin(), v.end(), l.begin());
print(l); //cannot call this
}
问题是我想要相同的函数print()
来打印矢量以及列表给我。
我尝试了以下
void print(t <t> &v);
我们可以这样做吗?我也看过使用ostream迭代器的解决方案 用于打印容器。这可以解决我的问题吗?
答案 0 :(得分:5)
正确的方法是使用迭代器:
template <class ForwardIter>
void print(ForwardIter begin, ForwardIter end)
{
for (; begin != end; ++begin)
cout << *begin << " ";
cout << endl;
}
这就是标准库函数与容器无关的方式,你也应该用这种方式编写函数。
这样做的原因是迭代器实际上是使用可以迭代的东西的一般方法。它可以是矢量,列表,c数组,文件,套接字等,你不需要知道或关心。
答案 1 :(得分:3)
您必须模拟您的类型向量或列表。例如,以下工作
template<typename Container>
void print(const Container& cont) {
for (auto const& x : cont) {
std::cout << x << " ";
}
std::cout << '\n';
}
int main() {
std::vector<int> v{1,2,3,4};
print(v);
std::list<int> l(v.size());
std::reverse_copy(v.begin(), v.end(), l.begin());
print(l);
}
输出
1 2 3 4
4 3 2 1
答案 2 :(得分:2)
是。我认为最好使用std::copy
。以下代码适用于数组和列表,只要容器具有ForwardIterator。
#include <iostream>
#include <vector>
#include <iterator>
template<typename T>
void print(const T& v) {
std::copy(v.begin(), v.end(), std::ostream_iterator<typename T::value_type>(std::cout, ", "));
}
int main()
{
std::vector<int> fiveInts = {1, 2, 3, 4, 5};
print(fiveInts);
return 0;
}
如果在容器上使用代码不支持ForwardIterator,则会出现编译错误。
ps:感谢Dieter和bipll,我改变了我的代码。是的,最好使用迭代器作为params而不是容器本身。
答案 3 :(得分:1)
最简单的解决方案是说你的print
函数可以处理任何事情:
template<typename t>
void print(t const &v) {
// Same body
}
这样可行,因为迭代任何标准容器都使用相同的代码。
但是在一个更大的计划中它可能会导致问题,因为它不会为任何不是标准容器的东西工作。理想情况下,您可以使用一些简单的模板元编程将其约束为适用的类型(使用例如enable_if
)。