2016-12-10 102 views
2

比方說,我想要一個class/struct類型,從integral_constant<size_t, N>繼承其中N是維度和尺寸如下實現:獲取一個std ::矢量/ STD的尺寸::陣列的數目

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

您可以爲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; 
} 
+0

這是我的,儘管如此。它必須受到限制。 – DeiDei

+0

@ T.C。對。固定。 – skypjack

3

有點難以定義「什麼是容器」。以下檢查爲value_type,iteratorconst_iterator嵌套的typedefs。根據需要調整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> {}; 
+0

這樣你就會報告'std :: vector >'的維數爲2 – skypjack

+0

@skypjack這對我來說很好。 'list '是一個容器。如果有人只想識別'std :: vector'和'std :: array',他們有你的答案。 (我質疑這樣做的有用性,考慮到這裏有許多'vector''類容器。) –

+0

我得到了這個問題 - 我想要找到一個向量鏈或一個array_鏈的維數。你會允許包含這兩種類型的鏈(以及所有其他容器)。 OP想要什麼? – skypjack