Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用“void\u t”检查类是否具有具有特定签名的方法_C++_Templates_Void_Template Meta Programming_C++14 - Fatal编程技术网

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, "");
    
首先,命名非静态成员函数的id表达式不能用作未计算的操作数(例如
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" );