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

时间:2017-07-14 15:32:01

标签: c++ c++11 templates sfinae

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

经过一些修补(好吧很有趣)和谷歌搜索,我可以得到类似下面的代码工作,问题是我不知道如何表达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的专精不会被使用,因为它无法推断所有类型。

1 个答案:

答案 0 :(得分:2)

由于您将在sf函数内调用重载,因此您应使用sf函数调用它来检查特定重载的可用性。

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