如何使用SFINAE检查静态const成员的存在

时间:2016-01-29 09:35:03

标签: c++ visual-studio-2010 sfinae

假设我有几个带有可选字段的结构:

struct Param1
{
    static const bool x = true;
};

struct Param2
{
};

想写模板功能

template <class ParamType>
bool ReturnParam();

如果存在静态字段ParamType::x,则应返回x,否则应返回false

我认为一些SFINAE魔法应该会有所帮助。

约束

我正在使用MSVC 2010,因此我无法使用大多数C ++ 11功能。

2 个答案:

答案 0 :(得分:0)

我使用以下特征:

#define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature)               \
    template <typename U>                                                   \
    class traitsName                                                        \
    {                                                                       \
    private:                                                                \
        template<typename T, T> struct helper;                              \
        template<typename T>                                                \
        static char check(helper<signature, &funcName>*);                   \
        template<typename T> static int check(...);                         \
    public:                                                                 \
        enum { value = sizeof(check<U>(0)) == sizeof(char)};                \
    }

DEFINE_HAS_SIGNATURE(has_x, T::x, const bool *);

然后SFINAE或标签调度:

template <typename T>
typename std::enable_if<has_x<T>::value, bool>::type
ReturnParam()
{
    return T::x;
}

template <typename T>
typename std::enable_if<!has_x<T>::value, bool>::type
ReturnParam()
{
    return false;
}

答案 1 :(得分:0)

此代码完美无缺:

template<typename T, typename MemberPtrGetter>
struct has_member_impl
{
private:
    template<typename U> static char Test(typename MemberPtrGetter::template type<U>*);
    template<typename U> static int Test(...);

public:
    static const bool value = sizeof(Test<T>(0)) == sizeof(char);
};


template <typename T, typename MemberPtrGetter>
struct has_member: public std::integral_constant<bool, has_member_impl<T, MemberPtrGetter>::value>
{
};

struct StaticMemberGetter
{
    template <typename T, const bool = T::x>
    struct type
    {
    };
};

struct Param1
{
    static const bool x = true;
};

struct Param2
{
};

template <typename Param, typename T = void> 
struct ExtractParam
{
    static const bool x = false;
};

template <typename Param>
struct ExtractParam<Param, std::true_type>
{
    static const bool x = Param::x;
};

template <typename Param>
bool ReturnParam()
{
    return ExtractParam<Param, has_member<Param, StaticMemberGetter>>::x;
}