c++:输出高维 vector 的 shape 并支持结构化绑定

来自学弟的问题:一个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);
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值