这被认为是SFINAE吗?

时间:2013-06-15 14:05:40

标签: c++ c++11 sfinae

我在一周前询问了一个问题,询问我如何能够简单地实例化一个类模板,只要它所采用的类型具有特定的成员函数。在我的回答中,我得到了一个复杂的解决方案。但后来我试着自己做。我只是想知道这是否足以弄清楚给定类型T是否有一个名为f的void函数,取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>’

如果是这样,为什么this thread?

中的其他答案如此复杂

1 个答案:

答案 0 :(得分:7)

是的,你已经用最简单,最惯用的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 {};