редактировать:
Хорошо, я понял это. Я использовал false_type
и true_type
в качестве аргумента для enable_if
, хотя должен был просто использовать bool
. :Икс
Кроме того, я решил, что класс is_map_like
будет лучше проверять, похож ли value_type
на std::pair<const Tkey, Tmapped>
. Итак, мой новый класс признаков выглядит так:
template<class Tcontainer>
struct is_map_like
{
private:
template<class TvalueType>
struct test
{
static const bool bvalue = false;
};
template<class TkeyType, class TmappedType>
struct test<std::pair<const TkeyType, TmappedType>>
{
static const bool bvalue = true;
};
public:
static const bool bvalue = test<typename Tcontainer::value_type>::bvalue;
};
Я хочу создать класс признаков типа is_map_like
, который проверяет наличие key_type
и mapped_type
. Я с трудом строю это. А пока я хотел бы просто проверить наличие key_type
. У меня пока следующее:
template<class T>
struct is_map_like
{
private:
template<typename C> static std::true_type test(typename C::key_type*);
template<typename C> static std::false_type test(...);
public:
typedef decltype(test<T>(0)) value;
};
value
здесь всегда возвращает false_type
. Насколько я понимаю, SFINAE должен позволить мне выбрать правильную перегрузку test
в зависимости от того, доступен ли C::key_type
.
Вот как я тестирую: во-первых, структура, специализированная с использованием enable_if
на is_map_like
:
// a class that will be specialized only for map-like types
template<class T, class Enable = void>
struct MyStruct
{
static void fn() { DebugLog(L"T is not a map type"); }
};
template<class T>
struct MyStruct<T, typename std::enable_if<is_map_like<T>::value>::type>
{
static void fn() { DebugLog(L"T is INDEED a map type"); }
};
И вот как я называю это во время выполнения:
void test_is_map()
{
MyStruct<std::vector<int>>::fn();
MyStruct<std::map<int, int>>::fn();
}
Выход:
T не является типом карты T не является типом карты
Что я делаю неправильно? Почему test(typename C::key_type*)
не используется даже для map
, у которого действительно есть key_type
? Или проблема в том, что я использую decltype
?
И бонус: есть ли для этого методы отладки? Как я могу проверить, как выбираются специализации, или даже получить подтверждение во время компиляции о расширении? Может быть, есть специфичные для VS расширения или инструменты отладки во время компиляции?