SFINAE 尝试使用布尔值给出编译器错误:"模板参数'T::value'涉及模板参数"

SFINAE tried with bool gives compiler error: "template argument ‘T::value’ involves template parameter"

本文关键字:参数 value 布尔值 SFINAE 错误 编译器      更新时间:2023-10-16

我尝试使用bool实现SFINAE(不像流行的void_技巧):

  template<typename T, bool = true>
  struct Resolve
  {
    static const bool value = false;
  };
  template<typename T>
  struct Resolve<T, T::my_value>
  {
    static const bool value = true;
  };

目标是专门化那些在里面定义了static const bool my_value = true;的类。如果它们被定义为false或未定义,则不要专门化它。例如

struct B1 {  // specialize Resolve for this case
  static const bool my_value = true;
};
struct B2 {  // don't specialize
  static const bool my_value = false;
};
struct B3 {};  // don't specialize

当对B1应用上述技巧时,它会给出编译错误:

Resolve<B1>::value;

错误:模板参数' T::my_value '涉及模板参数

我知道这可以通过其他方式实现。然而,我有兴趣知道,为什么它在这里给出编译器错误,它可以在这个代码本身解决吗?

实际上你所做的是被§14.5.4/9所禁止的,

部分专门化的非类型实参表达式不能包含部分专门化的模板形参,除非实参表达式是一个简单标识符。

技巧可以是在第二个模板参数中也使用类型,封装非类型值,如下所述:
template<bool b> struct booltype {};
template<typename T, typename B = booltype<true> >
struct Resolve
{
  static const bool value = false;
};
template<typename T>
struct Resolve<T, booltype<T::my_value> >
{
  static const bool value = true;
};

现在它编译罚款