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

Co chcę zrobić, to mieć check<T>::value być prawdziwe wtedy i tylko wtedy T jest std::map<A,B> lub std::unordered_map<A,B> i oba A i B być std::string. Więc zasadniczo check umożliwia sprawdzanie kompilacji typu T. Jak to zrobić?C++ wykrywa matrycy klasa

Odpowiedz

11

Częściowa specjalizacja, gdy chcesz, aby umożliwić dowolną porównawczej hasher, na klucz równej referencyjnymi i przydzielania:

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

Jeśli chcesz sprawdzić, czy T używał domyślnej wersji tych typów (tylko map<A,B>, a nie map<A,B,my_comp>, można pominąć argumenty szablonu i przejść do wyraźnej specjalizacji:

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

A jeśli chcesz ogólnie sprawdzić, czy jest to std::map lub std::unordered_map dowolnej kombinacji klucz/wartość (i komparator/hasher/itd.), Można go całkowicie generic pobrane z 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

korzystać z niektórych częściowa specjalizacja szablonu

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