检查类型 T 是否具有成员函数 SFINAE 的任何重载

Check if type T has any overloads of a member function, SFINAE

本文关键字:SFINAE 函数 任何 重载 成员 类型 是否 检查      更新时间:2023-10-16

考虑以下内容,我想检查我传递给其他函数的类型是否sf具有sf所需的成员函数T::mf,我知道返回类型和名称,但可以通过任意数量的重载。

经过一些修补(嗯,这很有趣.)和谷歌搜索,我可以让下面的代码工作,问题是我不知道如何表达print可以有可变数量的参数。

#include <type_traits>
#include <utility>

template <typename T,typename = void>
struct has_write : std::false_type {};
template <typename T>
struct has_write<T, decltype(std::declval<T>().write())> : std::true_type {};

template <typename T, typename R = void , typename ...Args>
struct has_print : std::false_type {};
// cant deduce, specialization never used
template <typename T, typename ...Args>
struct has_print<T, decltype(std::declval<T>().print(std::declval<Args>()...))> : std::true_type {};

struct Foo {
void write();
};
struct Bar {
int print(int, float, int);
};
int main(){
static_assert(has_write<Foo>::value, "Does not have write..");
static_assert(has_print<Bar>::value, "Does not have print..");
return 0;
}

上面用g++编译,但第二个assert失败了,clang更有帮助,告诉我has_print的专业化永远不会被使用,因为它无法推断出所有类型。

由于您将从函数内部调用重载sf因此您应该使用函数调用它的类型检查特定重载的可用性sf该类型。

根据定义,一般检查类中任何重载的可用性始终是一个 XY 问题,因为任何重载的可用性从来都不重要。您需要知道您可以使用给定的参数集调用名称。考虑一下:请求给定名称的任何重载的可用性在概念上与询问特定类是否有任何方法相同。显然你不会对它感兴趣吗?