我想创建一个可以处理任意维度向量的函数,psudocode中的函数:
template<class T>
void printVector(vector<T> t){
if(T==vector){
printf("[");
for(auto it=t.begin(),it!=t.end();++it){
printVector(*it);
}
printf("]");
}else{
printf("%d ",t);
}
}
例如:
vector<int> a;
a.push_back(12);
a.push_back(34);
printVector(a);
输出应为 [12 34],
vector<vector<int> > b;
vector<int> b1;
b1.push_back(1);
b1.push_back(2);
b.push_back(b1);
vector<int> b2;
b2.push_back(3);
b2.push_back(4);
b.push_back(b2);
printVector(b);
输出应为 [[1 2][3 4]]
C++模板系统支持递归。您的想法是正确的,但您需要重载该函数:
void printVector(int t) {
printf("%d ", t);
}
template<class T>
void printVector(std::vector<T> t) {
printf("[");
for(auto v : t){
printVector(v);
}
printf("]");
}
第一个函数处理基本情况。递归情况由第二个函数处理,应该很容易理解。
对于第二个示例,输出[[1 2 ][3 4 ]]
的示例,编译器最终生成printVector<vector<vector<int> > >()
、printVector<vector<int> >()
,并使用叶printVector(int)
。
当然,您应该给这个函数一个更好的名称。
既然问题被标记为C++,为什么不采取C++的方法呢?
template <template <typename ...> class CONTAINER, typename ... ARGS>
std::ostream &operator <<(std::ostream &o, const CONTAINER<ARGS ...> &container)
{
o << '[';
for (const auto &item : container)
{
o << item << ' ';
}
o << ']';
return o;
}
这个运算符将处理任何模板并尝试将其传递给ostream::operator <<
,因此它可以对ostream::operator <<
支持的任何类型的包含类型的容器有效。
如果我们还定义了一个自由ostream::operator <<
来处理std::pairs
它也可以用于std::map
:
template <typename F, typename S>
std::ostream &operator <<(std::ostream &o, const std::pair<F, S> &pair)
{
return o << pair.first << ':' << pair.second;
}
我已经用std::vector<int>
、std::vector<std::vector<int>>
、std::vector<std::vector<std::vector<int>>>
和std::valarray
和std::set
试过了;也用了std::map
。
当心!与std::string
一起使用是模棱两可的!因此,它不应该在打印字符串的范围内使用,或者我们应该寻找一种方法来禁用模板 std::string
.
编辑
Adam 建议的函数方法也适用于我的方法,它不会与std::ostream
的std::string
打印冲突:
template <typename T>
void printContainer(const T &value)
{
std::cout << value;
}
template <template <typename ...> class CONTAINER, typename ... ARGS>
void printContainer(const CONTAINER<ARGS ...> &container)
{
std::cout << '[';
for (const auto &item : container)
{
printContainer(item);
std::cout << ' ';
}
std::cout << ']';
}