2017-04-01 9 views
1

私が言って、特性クラスを持っている:テンプレートの特殊::マップ

template <class T> 
struct KeyValueTraits 
{ 
    typedef typename T::key_t key_t; 
    typedef typename T::value_t value_t; 
} 

今、私はstd::map

template < typename... Args > 
struct KeyValueTraits<typename std::map<Args...>::iterator > 
{ 
    typedef std::map<Args...> target_t; 
    typedef typename target_t::key_type key_t; 
    typedef typename target_t::mapped_type value_t; 
}; 

コンパイラのすべてのイテレータのために、この形質の特殊化を宣言したいと思いますエラーを発生させます:

error C2764: 'Args': template parameter not used or deducible in partial specialization

どのようにすべての可能性のある形の特質を宣言するのですか。std::map<...>::iterator

+1

できません。あなたがどんなことをやろうとしているのではありません。イテレータからコンテナ型を抽出する方法はありません。代わりに 'first'と' second'を使うことができます(C++ 11が必要です)。 –

+0

解決しようとしている問題は何ですか?値の型として 'std :: pair 'を持つイテレータではうまくいくソリューションがあります。 iterarorを取得したら、コンテナに関する情報を取得することは必ずしも可能ではありません。 –

答えて

1

これは1つの可能な解決策です(KeyValueTraitsテンプレートシグニチャが変更される可能性があるため変更されています)。

template <class T, class = void> 
struct KeyValueTraits 
{ 
    typedef typename T::key_t key_t; 
    typedef typename T::value_t value_t; 
}; 

template <class MapIter> 
struct KeyValueTraits<MapIter, 
         typename std::enable_if< 
         sizeof(std::declval<MapIter>()->first) && 
         sizeof(std::declval<MapIter>()->second) 
         >::type> 
{ 
    typedef decltype(std::declval<MapIter>()->first) key_t; 
    typedef decltype(std::declval<MapIter>()->second) value_t; 
}; 
+0

n.m. - 申し訳ありませんが...キーのタイプは、マップで 'key_type'ではありませんか? More:わかりませんが、私はOPが 'value_t 'を求めていると思っていますが、本当に' mapped_type' – max66

2

バリデーショナルのテンプレートパラメータを使用しているので、C++ 11ソリューションを受け入れることができます。

テンプレートの特殊化に基づいて、次のように提案します(本当に素晴らしいわけではありません)。キーのタイプは、std::map<>で、key_tしかしkey_typeではなく、値の型がvalue_tしかしmapped_typeではないという。数の

テイク

#include <map> 

template <typename X> 
struct with_kt 
{ 
    template <typename Y = X> 
    static constexpr bool getValue (int, typename Y::key_type * = nullptr) 
    { return true; } 

    static constexpr bool getValue (long) 
    { return false; } 

    static constexpr bool value { getValue(0) }; 
}; 

template <typename T, bool = with_kt<T>::value> 
struct KeyValueTraits; 

template <typename T> 
struct KeyValueTraits<T, true> 
{ 
    using key_t = typename T::key_type; 
    using value_t = typename T::mapped_type; 
}; 

template <typename T> 
struct KeyValueTraits<T, false> 
{ 
    using pair_t = decltype(* std::declval<T>()); 

    using key_t = typename std::remove_const< 
         decltype(std::declval<pair_t>().first)>::type; 
    using value_t = decltype(std::declval<pair_t>().second); 
}; 


using mil = std::map<int,long>; 

int main() 
{ 
    static_assert(std::is_same<KeyValueTraits<mil>::key_t, 
           KeyValueTraits<mil::iterator>::key_t 
           >::value, "!"); 

    static_assert(std::is_same<KeyValueTraits<mil>::value_t, 
           KeyValueTraits<mil::iterator>::value_t 
           >::value, "!!"); 

    static_assert(std::is_same<KeyValueTraits<mil>::key_t, 
           KeyValueTraits<mil::const_iterator>::key_t 
           >::value, "!!!"); 

    static_assert(std::is_same<KeyValueTraits<mil>::key_t, 
           KeyValueTraits<mil::reverse_iterator>::key_t 
           >::value, "!!!!"); 

    static_assert(std::is_same<KeyValueTraits<mil>::key_t, 
           KeyValueTraits<mil::const_reverse_iterator>::key_t 
           >::value, "!!!!!"); 
} 
+0

彼の解決策+1に感謝し、 'mapped_type'の間違いを修正しました。 – Dewfy

関連する問題