如何使用 SFINAE 检查静态常量成员的存在
How to check presence of static const member with SFINAE
假设我有几个带有可选字段的结构:
struct Param1
{
static const bool x = true;
};
struct Param2
{
};
并且想写模板函数
template <class ParamType>
bool ReturnParam();
如果静态字段 x
存在,应该 return ParamType::x
,否则应该 return false
我想一些 SFINAE 魔术应该有所帮助。
约束
我使用的是 MSVC 2010,所以我无法使用大部分 C++11 功能。
我使用以下特征:
#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;
}
此代码完美运行:
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;
}
假设我有几个带有可选字段的结构:
struct Param1
{
static const bool x = true;
};
struct Param2
{
};
并且想写模板函数
template <class ParamType>
bool ReturnParam();
如果静态字段 x
存在,应该 return ParamType::x
,否则应该 return false
我想一些 SFINAE 魔术应该有所帮助。
约束
我使用的是 MSVC 2010,所以我无法使用大部分 C++11 功能。
我使用以下特征:
#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;
}
此代码完美运行:
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;
}