来自学弟的问题:一个vector<vector<vector…> > > v, 写一个模板函数Size(), 然后可以直接auto [n,m,k] = Size(v)获取这个高维矩阵的各维维度?
#include <vector>
#include <string>
#include <cassert>
#include <array>
using std::vector;
template <typename T>
struct Dimension { static constexpr std::size_t value = 0; };
template <typename T>
struct Dimension<vector<T>> { static constexpr std::size_t value = 1 + Dimension<T>::value; };
template <typename T>
inline constexpr size_t dim = Dimension<T>::value;
template <typename T, size_t N = dim<T>>
std::array<size_t, N> shape(const T & a)
{
std::array<size_t, N> result{a.size()};
if constexpr (N>1) {
auto sub = shape(a[0]);
std::copy(sub.begin(), sub.end(), result.begin()+1);
}
return result;
}
#define assert_eq(a, b) assert((a) == (b))
int main() {
static_assert(dim<char> == 0);
static_assert(dim<vector<int>> == 1);
static_assert(dim<vector<vector<float>>> == 2);
static_assert(dim<vector<vector<vector<std::string>>>> == 3);
{
// assert_eq(shape(1), (std::array<size_t, 0>{})); // compile error
}
{
vector<int> b = {1, 2, 3};
assert_eq(shape(b), (std::array<size_t, 1>{3}));
}
{
vector<vector<std::string>> c = {{"a", "b", "c"}, {"c", "d", "e"}};
assert_eq(shape(c), (std::array<size_t, 2>{2, 3}));
}
{
vector<vector<vector<std::string>>> d = {
{{"a", "b", "c"}, {"c", "d", "e"}},
{{"a", "b", "c"}, {"c", "d", "e"}},
};
assert_eq(shape(d), (std::array<size_t, 3>{2, 2, 3}));
auto [a, b, c] = shape(d);
assert_eq(a, 2);
assert_eq(b, 2);
assert_eq(c, 3);
}
}