Вопрос

edit:

OK I figured it out. I was using false_type and true_type as an argument to enable_if when I should have just used bool. :x

Further, I have decided that a is_map_like class would be better to check if value_type is like, std::pair<const Tkey, Tmapped>. So, my new traits class looks like this:

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

I want to create a is_map_like type traits class that checks for key_type and mapped_type. I am having a hard time building this. For now I'd like to just check for key_type. I have the following so far:

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 here seems to always return false_type. As I understand, SFINAE should allow me to choose the right test overload based on whether C::key_type is accessible.

Here is how I'm testing: First, a struct that is specialized using enable_if on 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"); }
};

And here's how I call it at runtime:

void test_is_map()
{
    MyStruct<std::vector<int>>::fn();
    MyStruct<std::map<int, int>>::fn();
}

The output:

T is not a map type T is not a map type

What am I doing wrong? Why is the test(typename C::key_type*) not used even for the map, which indeed has a key_type? Or is the problem with my usage of decltype?

And bonus: are there any debugging techniques for this? How can I inspect how specializations are chosen, or even get a verification at compile-time about expansion? Maybe there are VS-specific extensions or compile-time debugging tools?

Это было полезно?

Решение

The value in the SFINAE structure is a type.

Make it:

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

and it will work

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top