10

大约一周前,我问了一个问题,询问我如何能够简单地实例化一个类模板,只有当它采用的类型具有特定的成员函数时。在我的回答中,我得到了一种复杂的解决方案。但后来我试着自己做。我只是想知道这是否足以确定给定类型T是否有一个名为f0 参数的 void 函数。

#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>’

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

4

1 回答 1

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 {};
于 2013-06-15T14:17:46.980 回答