2016-12-10 5 views
2

はのは、私はNが次元であり、次のように寸法が達成されintegral_constant<size_t, N>から継承し、class/structタイプをしたいとしましょう:は、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 

しかし、これは明らかに次元の数は、(理論的には)無限の可能として、完璧ではありません。これに汎用的な解決策を達成する方法はありますか?

提案:std::vectorが、これは動作しません、他のテンプレートパラメータを持っているので

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

を:私はこの方向に行ってきましたが、ないさらに。

答えて

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,iterator、およびconst_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> {}; 
+0

このようにして、 'std :: vector >'の次元は2であると報告します。 – skypjack

+0

@skypjackこれは私にとってうまくいきます。 'リスト'はコンテナです。誰かが 'std :: vector'と' std :: array'を正確に認識したいだけなら、彼らはあなたの答えを持っています。 (そこに無数の「ベクトル」のようなコンテナがあることを考慮して、そうすることの有用性に疑問を呈します。) –

+0

私は質問を得ました - _Iベクトルの連鎖または配列の連鎖の次元を求めます。両方のタイプ(および他のすべてのコンテナも同様)を含むチェーンを許可します。それはOPが望んでいるものですか? – skypjack

関連する問題