为什么这个traits类不起作用,测试一个类是否有某个typedef?

时间:2014-05-14 09:13:18

标签: c++ visual-c++ sfinae typetraits enable-if

编辑:

好的,我明白了。当我刚刚使用false_type时,我使用true_typeenable_if作为bool的参数。 :X

此外,我已经决定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_typemapped_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?或者是我使用{{1}}的问题?

还有奖励:这有什么调试技巧吗?如何检查专业化的选择,甚至在编译时获得有关扩展的验证?也许有特定于VS的扩展或编译时调试工具?

1 个答案:

答案 0 :(得分:3)

SFINAE结构中的值是一种类型。

成功:

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

它会起作用