C ++模板使用模板递归打印向量的向量
C++ template recursively print a vector of vector using template
#include <any>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
template<class T>
struct is_vector : std::false_type {};
template<class T>
inline constexpr bool is_vector_v = is_vector<T>::value;
template <typename T>
string VectorToString(const vector<T> &vec)
{
string res = "[";
int n = vec.size();
for (size_t i=0; i<n; i++) {
if constexpr(is_vector_v<T>) res += VectorToString(vec[i]);
else res += std::to_string(vec[i]);
if (i < n-1) res += ", ";
}
res += "]";
return res;
}
int main( int argc, char** argv )
{
vector<int> a = {1,2,3};
cout << VectorToString(a) << "\n";
vector<vector<int>> b = {{1,2,3}, {4,5,6}, {7,8,9}};
//cout << VectorToString(b);
vector<vector<vector<double>>> c = {{{1,2,3}, {4,5,6}}, {{7,8,9}}};
//cout << VectorToString(c);
return 0;
}
我正在尝试制作适用于任何矢量类型的打印函数,例如 Python。
我希望尽可能使用模板,但不确定如何使用。 struct is_vector
应该怎么做才能做到这一点?
如果模板解决方案不可行,那么我希望看到任何可能的解决方案。
一种选择是混合使用模板和运算符重载,如下所示。特别是,为 std::vector
重载 operator<<
。下面给出了一个非常粗糙的例子。它打印 std::vector
.
的所有元素
//this will be selected for 1D std::vector
template<typename T>
std::ostream& operator<<(std::ostream &os, const std::vector<T> &vec)
{
for(auto it = vec.begin(); it!=vec.end(); ++it)
{
os<< (*it)<<" ";
}
return os;
}
//for arbitrarily nested std::vector
template<typename T>
std::ostream& operator<<(std::ostream &os, const std::vector<std::vector<T>> &vec)
{
for(auto it = vec.begin(); it!=vec.end(); ++it)
{
os << *it;
}
return os;
}
int main()
{
std::vector<int> vec1{1,2,3};
std::cout<<vec1<<std::endl; //prints 1 2 3
std::vector<std::vector<int>> vec2 = {{1,2,3}, {4,5,6}, {7,8,9}}; //1 2 3 4 5 6 7 8 9
std::cout<<vec2<<std::endl;
std::vector<std::vector<std::vector<double>>> vec3{{{1,2,3}, {4,5,6}, {7,8,9}}, {{-1,-2,-3}, {-4,-5,-6}, {-10,-22,36}}, {{129,212,999}, {0,0,1}, {3,5,4}}};
std::cout<<vec3<<std::endl;
return 0;
}
以上程序的输出为:
1 2 3
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 -1 -2 -3 -4 -5 -6 -10 -22 36 129 212 999 0 0 1 3 5 4
Demo.
另一种选择是使用折叠表达式。
What should struct is_vector
looks like to do this?
看起来像模板偏特化的样子
template<class T>
struct is_vector : std::false_type {};
template<class T, class Alloc>
struct is_vector<std::vector<T, Alloc>> : std::true_type {};
#include <any>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
template<class T>
struct is_vector : std::false_type {};
template<class T>
inline constexpr bool is_vector_v = is_vector<T>::value;
template <typename T>
string VectorToString(const vector<T> &vec)
{
string res = "[";
int n = vec.size();
for (size_t i=0; i<n; i++) {
if constexpr(is_vector_v<T>) res += VectorToString(vec[i]);
else res += std::to_string(vec[i]);
if (i < n-1) res += ", ";
}
res += "]";
return res;
}
int main( int argc, char** argv )
{
vector<int> a = {1,2,3};
cout << VectorToString(a) << "\n";
vector<vector<int>> b = {{1,2,3}, {4,5,6}, {7,8,9}};
//cout << VectorToString(b);
vector<vector<vector<double>>> c = {{{1,2,3}, {4,5,6}}, {{7,8,9}}};
//cout << VectorToString(c);
return 0;
}
我正在尝试制作适用于任何矢量类型的打印函数,例如 Python。
我希望尽可能使用模板,但不确定如何使用。 struct is_vector
应该怎么做才能做到这一点?
如果模板解决方案不可行,那么我希望看到任何可能的解决方案。
一种选择是混合使用模板和运算符重载,如下所示。特别是,为 std::vector
重载 operator<<
。下面给出了一个非常粗糙的例子。它打印 std::vector
.
//this will be selected for 1D std::vector
template<typename T>
std::ostream& operator<<(std::ostream &os, const std::vector<T> &vec)
{
for(auto it = vec.begin(); it!=vec.end(); ++it)
{
os<< (*it)<<" ";
}
return os;
}
//for arbitrarily nested std::vector
template<typename T>
std::ostream& operator<<(std::ostream &os, const std::vector<std::vector<T>> &vec)
{
for(auto it = vec.begin(); it!=vec.end(); ++it)
{
os << *it;
}
return os;
}
int main()
{
std::vector<int> vec1{1,2,3};
std::cout<<vec1<<std::endl; //prints 1 2 3
std::vector<std::vector<int>> vec2 = {{1,2,3}, {4,5,6}, {7,8,9}}; //1 2 3 4 5 6 7 8 9
std::cout<<vec2<<std::endl;
std::vector<std::vector<std::vector<double>>> vec3{{{1,2,3}, {4,5,6}, {7,8,9}}, {{-1,-2,-3}, {-4,-5,-6}, {-10,-22,36}}, {{129,212,999}, {0,0,1}, {3,5,4}}};
std::cout<<vec3<<std::endl;
return 0;
}
以上程序的输出为:
1 2 3
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 -1 -2 -3 -4 -5 -6 -10 -22 36 129 212 999 0 0 1 3 5 4
Demo.
另一种选择是使用折叠表达式。
What should struct
is_vector
looks like to do this?
看起来像模板偏特化的样子
template<class T>
struct is_vector : std::false_type {};
template<class T, class Alloc>
struct is_vector<std::vector<T, Alloc>> : std::true_type {};