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

erkennen Was ich tun möchte, ist check<T>::value wahr sein zu haben, wenn und nur wenn T ein std::map<A,B> oder std::unordered_map<A,B> und beide A und Bstd::string sein. Im Grunde ermöglicht check Kompilierzeitprüfung des Typs T. Wie mache ich das?C++ Templat-Klasse

Antwort

11

Teil Spezialisierung, wenn Sie jeden Komparator, Hasher, Schlüssel equal-Komparator und allocator zulassen mögen:

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; 
}; 

Wenn Sie, wenn überprüfen mögen T verwendet die Standardversion dieser Typen (aka nur map<A,B> und nicht map<A,B,my_comp>, können Sie die Vorlage Argumente weglassen und gehen mit expliziter Spezialisierung:

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; 
}; 

Und wenn Sie in der Regel überprüfen wollen, ob es ein std::map oder std::unordered_map jeden Schlüssel/Wert-Kombination (und Vergleicher/Hasher/etc.) ist, können Sie sich ganz generic gehen, wie aus here genommen:

#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

Verwenden einig partielle Template-Spezialisierung

// 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; 
};