c – 为什么以下SFINAE测试无法检测模板成员函数?

使用GCC编译我总是从以下代码中得到错误.我相信这是一个编译器错误,但有人可能会更清楚.

#include <iostream>


template< class T > 
class has_apply { 

  typedef char yes[1];
  typedef char no[2];

  template< class U, U u > 
  struct binder {};

  template< class U, unsigned n >
  static yes& test( U*,
                        binder< void (U::*) ( const double& ),
                            &U::template apply< n >
                          >* = 0
                  );

  template< class U, unsigned n >
  static no& test( ... );

public:

  static const bool result =
         ( sizeof( yes ) == sizeof( test< T, 0u >( (T*)(0) ) ) );

}; 

class A {
public:
    template< unsigned n >
    void apply( const double& );

};

int main()
{
  std::cout << std::boolalpha << has_apply< A >::result << '\n';
  return( 0 );
}

最佳答案 我无法理解为什么,但我能够通过不取出U *并通过拉出活页夹类型的声明来使代码工作:

template< class T > 
class has_apply { 

public:
  typedef char yes[1];
  typedef char no[2];

  template< class U, U u > 
  struct binder {};
  typedef binder< void (T::*)(const double&), &T::template apply<0u> > b;

  template < typename V, unsigned n >
  struct declare
  {
    typedef binder< void (V::*)(const double&), &V::template apply<n> > type;
  };

  template< typename U, unsigned n >
  static yes& test( typename declare<U,n>::type * );

  template< class U, unsigned n >
  static no& test( ... );


  static const bool result =
         ( sizeof( yes ) == sizeof( test< T, 0u >( 0 ) ) );

}; 

实际上,您可以通过从函数中删除unsigned参数并在“declare”中的typedef中粘贴0u来简化此操作.

同样,我无法解释为什么这个中间元函数是必要的,但它是必需的,上述工作在MSVC 2010中

点赞