首页 > 解决方案 > 模板化检查是否存在带有参数列表的类成员函数?

问题描述

与此问题类似,是否可以使用 SFINAE 来确定类型是否具有带有特定参数的成员函数?没有在另一个问题中回答的参数列表,并且std::void_t示例说它工作正常。(我支持后者。)但是,如果我尝试使用 extra 添加对参数 lust 的检查,std::decltype<>()它会以template parameters not deducible in partial specialization. 有没有办法扩展这个方法来检查某些参数类型?

示例代码:


#include <type_traits>

class A {
public :
    void a(){}
    void b(int val){}
};

class B {
public :
    void b(float val){}
};

// --- Has function a() without arguments

template <typename T, typename = void> struct has_a : std::false_type
{
};

template <typename T> struct has_a<T, std::void_t<decltype(std::declval<T>().a())>> : std::true_type
{
};

template <typename T> constexpr bool has_a_v = has_a<T>::value;

// This is OK:
static_assert(true == has_a_v<A>); 
static_assert(false == has_a_v<B>);

// --- Has function b() with one argument of one given type

template <typename T, typename U, typename = void> struct has_b : std::false_type
{
};

template <typename T ,typename U> struct has_b<T, std::void_t<decltype(std::declval<T>().b(std::declval<U>()))>> : std::true_type
{
};

template <typename T, typename U> constexpr bool has_b_v = has_b<T, U>::value;

// This fails with `template parameters not deducible in partial specialization`:
static_assert(true == has_b_v<A, int>);
static_assert(false == has_b_v<B, int>);

static_assert(false == has_b_v<A, float>);
static_assert(true == has_b_v<B, float>);

int main () { return 0;}

标签: c++templatesc++17sfinae

解决方案


是的。void_t检查b类中成员函数的示例 B

decltype( static_cast<void(B::*)(float)>(&B::b) )

这是如果您想检查确切的签名。你的方式也很好(一旦你按照问题下的评论修复它),但它实际上检查成员函数是否可以使用某些类型的参数调用(并忽略返回类型)


推荐阅读