获取std :: vector / std :: array的维数

时间:2016-12-10 23:12:29

标签: c++ c++11 templates c++14

假设我想要一个class/struct类型,继承自integral_constant<size_t, N>,其中N是维度,维度的实现如下:

template<class T>
struct dimension;

template<class T>
struct dimension<vector<T>> : integral_constant<size_t, 1> {};

template<class T>
struct dimension<vector<vector<T>>> : integral_constant<size_t, 2> {};

然后

cout << dimension<vector<int>>::value;         // 1
cout << dimension<vector<vector<int>>>::value; // 2

但显然这并不完美,因为维度的数量可以是无限的(理论上)。有没有办法实现这个通用的解决方案?

建议:我朝着这个方向前进,但没有进一步:

template<class T, class... Tn>
struct dimension<vector<Tn...>> : integral_constant<size_t, sizeof...(Tn)> {};

由于std::vector有其他模板参数,因此无效。

2 个答案:

答案 0 :(得分:3)

有点难以定义&#34;什么是容器&#34;。以下检查value_typeiteratorconst_iterator嵌套typedef。根据需要调整void_t检查。 (例如,如果您只想将可以下标的内容识别为容器,则将decltype(std::declval<T&>()[0])添加到列表中。)

请注意dimension_impl的专精调用dimension。这样,您就可以将dimension专门用于容器般的事情,而不想将其视为容器(std::string会浮现在脑海中)。

template<class T> struct dimension;

namespace details {    
    template<class T, class = void>
    struct dimension_impl {
        static constexpr std::size_t value = 0;
    };

    template<class T>
    struct dimension_impl<T, std::void_t<typename T::value_type,
                                         typename T::iterator,
                                         typename T::const_iterator>> {
        static constexpr std::size_t value = 1 + dimension<typename T::value_type>::value;
    };
}

template<class T>
struct dimension : std::integral_constant<std::size_t, 
                                          details::dimension_impl<T>::value> {};

答案 1 :(得分:2)

您可以为std::vector执行此操作(请注意std::vector的模板参数列表长于1):

template<typename T>
struct dimension { static constexpr std::size_t value = 0; };

template<typename T, typename... V>
struct dimension<std::vector<T, V...>>{
    static constexpr std::size_t value = 1 + dimension<T>::value;
};

这适用于std::array

template<typename>
struct dimension { static constexpr std::size_t value = 0; };

template<typename T, std::size_t N>
struct dimension<std::array<T, N>>{
    static constexpr std::size_t value = 1 + dimension<T>::value;
};

它遵循一个最小的工作示例:

#include<vector>
#include<iostream>

template<typename T>
struct dimension { static constexpr std::size_t value = 0; };

template<typename T, typename... V>
struct dimension<std::vector<T, V...>>{
    static constexpr std::size_t value = 1 + dimension<T>::value;
};

int main() {
    std::cout << dimension<std::vector<std::vector<int>>>::value << std::endl;
}