Почему этот класс признаков не работает, чтобы проверить, имеет ли класс определенный typedef?

редактировать:

Хорошо, я понял это. Я использовал 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 расширения или инструменты отладки во время компиляции?


person tenfour    schedule 14.05.2014    source источник


Ответы (1)


Значение в структуре SFINAE является типом.

Сделай это:

static constexpr bool value = decltype(test<T>(0))::value;

и это будет работать

person Community    schedule 14.05.2014