iam*_*ind 3 c++ macros templates class member
这个Q是以下的扩展:
是否可以编写C++模板来检查函数的存在?
是否有任何有助于找到的实用程序:
有了std::experimental::is_detected和std::experimental::disjunction你可以这样做:
//check for a type member named foo
template <typename T>
using foo_type_t = typename T::foo;
//check for a non-type member named foo
template <typename T>
using foo_non_type_t = decltype(&T::foo);
template <typename T>
using has_foo = disjunction<is_detected<foo_type_t, T>,
is_detected<foo_non_type_t, T>>;
Run Code Online (Sandbox Code Playgroud)
然后你可以随意使用has_foo<my_class>::value.
上面的内容不仅适用于类型和成员函数,而且您可以通过使用特征来轻松约束它std::is_member_function_pointer,std::is_member_object_pointer如果您愿意的话.
要提供可选参数,可以使用std::experimental::is_detected_exact帮助程序.
请注意,如果从我链接的页面中获取上述特征的实现,则可以将其与C++ 14一起使用.对disjunction代码进行微小更改将允许您在C++ 11中使用它.
#define HasMember(NAME) \
template<class Class, typename Type = void> \
struct HasMember_##NAME \
{ \
typedef char (&yes)[2]; \
template<unsigned long> struct exists; \
template<typename V> static yes Check (exists<sizeof(static_cast<Type>(&V::NAME))>*); \
template<typename> static char Check (...); \
static const bool value = (sizeof(Check<Class>(0)) == sizeof(yes)); \
}; \
template<class Class> \
struct HasMember_##NAME<Class, void> \
{ \
typedef char (&yes)[2]; \
template<unsigned long> struct exists; \
template<typename V> static yes Check (exists<sizeof(&V::NAME)>*); \
template<typename> static char Check (...); \
static const bool value = (sizeof(Check<Class>(0)) == sizeof(yes)); \
}
Run Code Online (Sandbox Code Playgroud)
用法:只需使用您想要查找的任何成员调用宏即可:
HasMember(Foo); // Creates a SFINAE `class HasMember_Foo`
HasMember(i); // Creates a SFINAE `class HasMember_i`
Run Code Online (Sandbox Code Playgroud)
现在我们可以利用以下方式HasMember_X签入X任何内容:class
#include<iostream>
struct S
{
void Foo () const {}
// void Foo () {} // If uncommented then type should be mentioned in `HasMember_Foo`
int i;
};
int main ()
{
std::cout << HasMember_Foo<S, void (S::*) () const>::value << "\n";
std::cout << HasMember_Foo<S>::value << "\n";
std::cout << HasMember_i<S, int (S::*)>::value << "\n";
std::cout << HasMember_i<S>::value << "\n";
}
Run Code Online (Sandbox Code Playgroud)
渔获:
class
不得有重载方法。如果有,那么这个技巧就失败了。即,即使指定成员出现多次,结果也将是false。B的基数,则or或将给出Svoid B::Bar ()HasMember_Bar<S, void (B::*)()>::valueHasMember_Bar<S, void (S::*)()>::valueHasMember_Bar<S>::valuefalse