2012-10-16 27 views
6
Ne yapmak istiyor ve yalnızca T bir std::map<A,B> veya std::unordered_map<A,B> hem A ve olmayacak std::string B ise check<T>::value doğru sahip olmaktır
template<typename T> 
struct check 
{ 
    static const bool value = false; 
}; 

. Yani temel olarak check, T türünün derleme zamanı denetimini etkinleştirir. Bunu nasıl yaparım?C şablonu sınıfı tespit ++

cevap

11

herhangi karşılaştırıcı, hasher, anahtar eşit karşılaştırıcı ve allocator izin vermek istediğinizde Kısmi uzmanlaşma: Eğer kontrol etmek istiyorsanız

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

T, bu türlerin varsayılan sürümünü (yalnızca map<A,B> ve map<A,B,my_comp> değil, şablon bağımsız değişkenlerini atlayabilir ve açık özelleştirmeyle birlikte kullanabilirsiniz:

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

bunu bir std::map veya herhangi bir tuşa/değer kombinasyonu std::unordered_map (ve karşılaştırıcı vb/hasher /) ise genellikle kontrol etmek istiyorum Ve eğer here alınan olarak tamamen jenerik gidebilir:

#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

kullanın bazı kısmi şablon uzmanlık

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