为什么SFINAE导致编译器错误,它应该工作

Why SFINAE results in compiler error where it should have worked?

本文关键字:工作 错误 SFINAE 编译器 为什么      更新时间:2023-10-16

我试图实现一个元程序,发现如果给定的指针类型是const或不。例如

  • is_const<TYPE*>::value应该是false
  • is_const<const TYPE*>::value应为true

代码如下:

template<class TYPE>
struct is_const
{
  typedef char yes[3];
  template<typename T>
  struct Perform
  {
    static yes& check (const T*&);
    static char check (T*&);
  };  
  TYPE it; 
  enum { value = (sizeof(Perform<TYPE>::check(it)) == sizeof(yes)) };  
};

编译器的错误信息是:

In instantiation of ‘is_const<int*>’:
instantiated from here
error: no matching function for call to ‘is_const<int*>::Perform<int*>::check(int*&)’
note: candidates are: static char (& is_const<TYPE>::Perform<T>::check(const T*&))[3] [with T = int*, TYPE = int*]
note: static char is_const<TYPE>::Perform<T>::check(T*&) [with T = int*, TYPE = int*]

我的焦点已经转移到错误信息。如果你看到最后一行:

note: static char is_const<TYPE>::Perform<T>::check(T*&) [with T = int*, TYPE = int*]

如果我们真的替换T = int*TYPE = int*,那么它真的应该匹配适当的功能(char check())。我很想知道这里出了什么问题。

为什么这么兜圈子?那么直接的trait类呢:

#include <functional>
template <typename T> struct is_const_ptr : std::false_type { };
template <typename T> struct is_const_ptr<const T *> : std::true_type { };
struct Foo {};
int main()
{
  std::cout << is_const_ptr<Foo*>::value << is_const_ptr<const Foo*>::value << std::endl;
}

你的问题是:

static yes& check (const T*&);
static char check (T*&);

当您实例化is_const<int*>时,您的函数定义扩展为:

static yes& check (const int**&);
static char check (int**&);
但是,您的临时项(TYPE it)的类型是int*,就像您指定的那样。您需要更改check函数签名以删除指针说明符,如下所示:
static yes& check (const T&);
static char check (T&);

你的代码有两处错误。

首先,下面的

static yes& check (const T*&);
static char check (T*&);

必须改为

static yes& check (const T&);
static char check (T&);
其次,it成员必须是static
static TYPE it;

或者,将((TYPE)0)传递给检查函数。不需要成员

相关文章: