我计划编写一个可以打印任何容器的所有数据的函数。换句话说,我可以使用不同的容器类型,如vector,deque或list,我可以使用不同的数据类型(整数,双精度或字符串)调用它。 模板函数可以通过编译器,但我不知道如何调用它。
#include <cstdlib>
#include <stdio.h>
#include <iostream>
#include <list>
using namespace std;
template <typename C, template <typename C> class M>
void print(M<C> data){
typename M<C>::iterator it;
for(it=data.template begin();it!=data.template end();++it){
cout<<*it<<" ";
}
cout<<endl;
}
int main(int argc, char** argv) {
list<int> data;
for(int i=0;i<4;i++){
data.push_back(i);
}
print<int>(data); //compile error
print<int, list>(data); //compile error
return 0;
}
错误讯息: main.cpp:35:20:错误:没有匹配函数来调用'print(std :: list&amp;)' main.cpp:35:20:注意:候选人是: main.cpp:21:6:注意:模板类M> void print(M)
一些相关主题: template function for multiple containers and data types http://louisdx.github.io/cxx-prettyprint/
答案 0 :(得分:3)
如评论中所述,std::list
实际上有多个模板参数(第二个参数是分配器)。此外,print
不需要采用两个模板参数;您可以简单地在整个容器类型上对其进行参数化:
#include <iostream>
#include <iterator>
#include <list>
using namespace std;
template <typename C>
void print(const C &data){
for(auto it=begin(data);it!=end(data);++it){
cout<<*it<<" ";
}
cout<<endl;
}
int main(int argc, char** argv) {
list<int> data;
for(int i=0;i<4;i++){
data.push_back(i);
}
print(data);
return 0;
}
正如在另一个答案中所指出的,如果你可以使用C ++ 11特性,则range-for循环优于上面使用的显式迭代器。如果你不能(这意味着没有auto
或std::begin
或std::end
),那么:
template <typename C>
void print(const C &data){
for(typename C::const_iterator it=data.begin();it!= data.end();++it){
cout<<*it<<" ";
}
cout<<endl;
}
请注意,由于我们通过const引用获取data
,因此我们需要使用const_iterator
。
答案 1 :(得分:2)
使用c ++ 11,您可以将其简化为:
template <typename C>
void print(const C &data){
for (auto &elem : data)
cout << elem << " ";
cout << endl;
}
并使用print(data)
进行调用。您还可以使用std::for_each
或copy it directly into cout。