为什么返回SFINAE转换运算符不起作用?

use*_*108 0 c++ type-conversion c++17

struct A
{
  template <typename T>
  constexpr explicit operator
  std::enable_if_t<
    std::is_same<std::decay_t<T>, int>{},
    int
  >() const noexcept
  {
    return -1;
  }
};

int main()
{
  A a;

  std::cout << int(a) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

错误是clang-7.0.1

<source>:21:16: error: no matching conversion for functional-style cast from 'A' to 'int'
  std::cout << int(a) << std::endl;
               ^~~~~
<source>:7:22: note: candidate template ignored: couldn't infer template argument 'T'
  constexpr explicit operator
                     ^
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 5

该模式仅对转换功能不起作用。问题是,为了确定是否a可转换为int,我们寻找operator int()--但得到的是:

std::enable_if_t<std::is_same<std::decay_t<T>, int>{}, int>
Run Code Online (Sandbox Code Playgroud)

那是一个非推论的上下文-因此我们找不到int

您必须将条件移动到默认参数中:

template <typename T, std::enable_if_t<std::is_same_v<T, int>, int> = 0>
constexpr explicit operator T() const noexcept { return -1; }
Run Code Online (Sandbox Code Playgroud)

这样,我们就可以推断出结果T,然后让SFINAE发挥其魔力。请注意,decay由于我们没有任何参考,因此您不需要。

  • 如果它以`,bool&gt; = true&gt;`而不是`,int&gt; = 0&gt;`结束,可能会减少混乱。仍然同样具有魔力,但避免在不相关的上下文中重用“ int”类型,这可能会使此处感到困惑。 (3认同)
  • @ user1095108如果这意味着我在猜测,那就没有冲突。您不能将参数粘贴在`()`s中 (2认同)