使用`void_t`检查类是否具有带有特定签名的方法

问题描述 投票:7回答:3

此刻,我是using this method to check if a class has a method with a specific signature.

[参加Walter E. Brown's metaprogramming CppCon2014 talk之后,我开始怀疑是否可以在这种特殊情况下使用void_t来使代码更清晰和可读性。

然而,我在思考void_t时遇到了麻烦-到目前为止,我了解到void_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 { };

如果decltype(T::type)是有效表达式,则has_type_data_member<T>将是一个真正的编译时常量。因此,我们确定T具有一个称为data的成员字段。

我想使用相同的方法来检查类型T是否具有带有特定名称和特定签名的方法。

假设我要检查T是否具有称为getCount()的方法,该方法返回int。这是我期望的工作((Ideone.com link))

template< class, class = void >
struct hasGetCount : false_type { };

template< class T >
struct hasGetCount<T, VoidT<decltype(T::getCount)>> 
: std::is_same<decltype(std::declval<T>().getCount()), int>::type { };

不幸的是,static_assert测试未通过。

我在做什么错?在这种情况下可以使用void_t吗?

奖励问题:

  • 我还如何检查方法签名是否等于用户在原始实现中通过的签名?
  • 我可以使用宏来定义这类辅助结构,如下所示:

 DEFINE_METHOD_CHECKER(hasGetCount, getCount);
 // ...
 static_assert(hasGetCount<ClassWithGetCount>::value == true, "");

是否有可能避免先定义struct然后检查结构的值?我的意思是,是否可以使用宏编写类似这样的内容?示例:

 static_assert(CHECK_METHOD(ClassWithGetCount, getCount)::value == true, "");

目前,我正在使用此方法来检查类是否具有带有特定签名的方法。在参加了Walter E. Brown的元编程CppCon2014演讲之后,我开始怀疑void_t是否可以...

c++ templates void template-meta-programming c++14
3个回答
6
投票

首先,命名为非静态成员函数的id-expression


6
投票

您可以使用void_t轻松地验证getCount的返回类型可转换为int


0
投票

如果您还想检查函数的参数及其返回类型,则类似于Casey的建议

© www.soinside.com 2019 - 2024. All rights reserved.