2012-10-16 8 views
6
template<typename T> 
struct check 
{ 
    static const bool value = false; 
}; 

Quello che voglio fare è di avere check<T>::value essere vero se e solo se è una Tstd::map<A,B> o std::unordered_map<A,B> ed entrambi A e B essere std::string. Quindi, in pratica, check abilita il controllo in fase di compilazione del tipo T. Come faccio a fare questo?C++ rilevare classe template

risposta

11

specializzazione parziale per quando si vuole consentire a qualsiasi confronto, Hasher,-uguale-comparatore chiave e allocatore:

template<class Comp, class Alloc> 
struct check<std::map<std::string, std::string, Comp, Alloc>>{ 
    static const bool value = true; 
}; 

template<class Hash, class KeyEq, class Alloc> 
struct check<std::unordered_map<std::string, std::string, Hash, KeyEq, Alloc>>{ 
    static const bool value = true; 
}; 

Se si vuole verificare se T utilizzato la versione predefinita di quei tipi (aka solo map<A,B> e non map<A,B,my_comp>, è possibile omettere gli argomenti del modello e andare con specializzazione esplicita:

template<> 
struct check<std::map<std::string, std::string>>{ 
    static const bool value = true; 
}; 

template<> 
struct check<std::unordered_map<std::string, std::string>>{ 
    static const bool value = true; 
}; 

E se si desidera controllare in generale, se si tratta di un std::map o std::unordered_map di qualsiasi combinazione chiave/valore (e di confronto/Hasher/ecc), si può andare completamente generico preso dal here:

#include <type_traits> 

template < template <typename...> class Template, typename T > 
struct is_specialization_of : std::false_type {}; 

template < template <typename...> class Template, typename... Args > 
struct is_specialization_of< Template, Template<Args...> > : std::true_type {}; 

template<class A, class B> 
struct or_ : std::integral_constant<bool, A::value || B::value>{}; 

template<class T> 
struct check 
    : or_<is_specialization_of<std::map, T>, 
     is_specialization_of<std::unordered_map, T>>{}; 
3

Usa qualche modello di specializzazione parziale

// no type passes the check 
template< typename T > 
struct check 
{ 
    static const bool value = false; 
}; 

// unless is a map 
template< typename Compare, typename Allocator > 
struct check< std::map< std::string, std::string, Compare, Allocator > > 
{ 
    static const bool value = true; 
}; 

// or an unordered map 
template< typename Hash, typename KeyEqual, typename Allocator > 
struct check< std::unordered_map< std::string, std::string, Hash, KeyEqual, Allocator > > 
{ 
    static const bool value = true; 
};