2017-04-01 1 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

한 가지 가능한 해결책이 있습니다 (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'이 아니십니까? 더보기 : 확실하지는 않지만 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