C++ 使用“void\u t”检查类是否具有具有特定签名的方法
现在,我很高兴 参加会议后,我开始怀疑C++ 使用“void\u t”检查类是否具有具有特定签名的方法,c++,templates,void,template-meta-programming,c++14,C++,Templates,Void,Template Meta Programming,C++14,现在,我很高兴 参加会议后,我开始怀疑void\t是否可以用于这种特殊情况,以使代码更干净、更可读 然而,我在思考void\u t方面遇到了困难-到目前为止,我知道void\u t可以帮助我在编译时确定表达式是否有效 例如: template< class, class = void > struct has_type_data_member : false_type { }; template< class T > struct has_type_data_membe
void\t
是否可以用于这种特殊情况,以使代码更干净、更可读
然而,我在思考void\u t
方面遇到了困难-到目前为止,我知道void\u t
可以帮助我在编译时确定表达式是否有效
例如:
template< class, class = void >
struct has_type_data_member : false_type { };
template< class T >
struct has_type_data_member<T, void_t<decltype(T::data)>> : true_type { };
不幸的是,static\u assert
测试没有通过
我做错了什么?在这种情况下是否可以使用void\t
奖金问题:
- 如何检查方法签名是否与用户在原始实现中传递的签名相同
- 我可以使用宏来定义此类帮助器结构,如下所示:
DEFINE_METHOD_CHECKER(hasGetCount, getCount); // ... static_assert(hasGetCount<ClassWithGetCount>::value == true, "");
decltype
的操作数)。此外,您应该检查整个函数调用表达式是否格式正确,而不仅仅是是否有名为getCount
的成员:
template< class, class = void >
struct hasGetCount : false_type { };
template< class T >
struct hasGetCount<T, VoidT<decltype(std::declval<T>().getCount())>>
: std::is_same<decltype(std::declval<T>().getCount()), int>::type { };
template< class, class = void >
struct hasGetCount : false_type { };
template< class T >
struct hasGetCount<T,
VoidT<
decltype(std::declval<int&>() = std::declval<T>().getCount())
>> : std::true_type {};
您可以使用
void\u t
轻松验证getCount
的返回类型是否可转换为int
,而不是两次写入decltype
:
template< class, class = void >
struct hasGetCount : false_type { };
template< class T >
struct hasGetCount<T, VoidT<decltype(std::declval<T>().getCount())>>
: std::is_same<decltype(std::declval<T>().getCount()), int>::type { };
template< class, class = void >
struct hasGetCount : false_type { };
template< class T >
struct hasGetCount<T,
VoidT<
decltype(std::declval<int&>() = std::declval<T>().getCount())
>> : std::true_type {};
template
结构hasGetCount:false_type{};
模板
结构hasGetCount>:std::true_type{};
()
希望C++17面世时,我们能够更轻松地使用以下工具:
模板
概念bool hasGetCount=requires(T){
{t.getCount()}->int;
};
如果您还想检查函数的参数及其返回类型,与建议的类似
template<typename... > struct Voider { using Type = void; };
template<typename... TArgs> using void_t = typename Voider<TArgs...>::Type;
template<class, typename, class = void>
struct hasGetCount : false_type { };
template< class T, typename Ret, typename... Args>
struct hasGetCount<T, Ret(Args...),
void_t<decltype(std::declval<Ret&>()
= std::declval<T>().getCount(std::declval<Args>()...))
>> : std::is_same<
decltype(std::declval<T().getCount(std::declval<Args>()...)),
Ret>::type {};
template struct Voider{using Type=void;};
使用void\u t=typename Voider::Type的模板;
模板
结构hasGetCount:false_type{};
模板<类T,类型名Ret,类型名。。。Args>
结构hasGetCount:std::是否相同<
decltype(std::declval::type{};
用法:
class A {
public:
int member;
int getCount() {return 0;}
};
static_assert( hasGetCount<A, int(void)>::value , "A" );
A类{
公众:
国际会员;
int getCount(){return 0;}
};
静态断言(hasGetCount::value,“A”);
命名非静态成员函数的id表达式不能用于decltype
@T.C.:我明白了-是否有其他方法根据类型是否有/没有方法来生成有效/无效表达式?declval
生成一个xvalue,因此如果要检查getCount()
可以在左值上调用,使用declval
(自ref限定符起相关).SFINAE是涉及函数模板的类模板专门化和重载解析规则的结果。enable_(如果
不是函数模板的必要或充分成分)。如果要以函数模板形式重写测试,请使用类似于template typename std::is_same::type test(int)的方法
是一个很好的开始,如果,则不使用启用。\u。尽管此检查仅适用于=
的lhs上的非类类型,否则,您正在检查可分配性。类似地,就我所见,它(直接)不适用于函数类型和数组。
template<typename... > struct Voider { using Type = void; };
template<typename... TArgs> using void_t = typename Voider<TArgs...>::Type;
template<class, typename, class = void>
struct hasGetCount : false_type { };
template< class T, typename Ret, typename... Args>
struct hasGetCount<T, Ret(Args...),
void_t<decltype(std::declval<Ret&>()
= std::declval<T>().getCount(std::declval<Args>()...))
>> : std::is_same<
decltype(std::declval<T().getCount(std::declval<Args>()...)),
Ret>::type {};
class A {
public:
int member;
int getCount() {return 0;}
};
static_assert( hasGetCount<A, int(void)>::value , "A" );