这被认为是SFINAE吗?

Is this considered SFINAE?

本文关键字:SFINAE 认为是      更新时间:2023-10-16

一周前我问了一个问题,问我如何能够简单地实例化一个类模板,只有当它接受的类型有一个特定的成员函数。在我的回答中,我得到了一个复杂的解决方案。但后来我试着自己做。我只是想知道这是否足以计算出给定类型T有一个名为f的空函数,它有0个参数。

#include <type_traits>
#include <utility>
template <typename T, typename = void>
struct has_f : std::false_type { };
template <typename T>
struct has_f<
    T,
    decltype(std::declval<T>().f(), void())> : std::true_type { };
template <typename T, typename = typename std::enable_if<has_f<T>::value>::type>
struct A { };
struct B
{
    void f();
};
struct C { };
template class A<B>; // compiles
template class A<C>; // error: no type named ‘type’ 
                     // in ‘struct std::enable_if<false, void>’

如果是这样,为什么其他的答案在这个线程这么复杂?

是的,你已经用c++ 11 SFINAE最简单、最习惯的风格解决了这个问题。

请注意,您没有检查返回类型是否为void,是否为非静态成员,是否没有参数。f可以不带参数地调用。它甚至可以是函子

检查返回void的虚成员非静态函数,使用

template <typename T>
struct has_f<T, decltype(void( static_cast< void (T::*)( void ) >( &T::f ) )) >
    : std::true_type {};
template <typename T>
struct has_f<T, decltype(void( static_cast< void (T::*)( void ) const >( &T::f ) )) >
    : std::true_type {};