SFINAE 超出过载分辨率

SFINAE outside of overload resolution?

本文关键字:分辨率 SFINAE      更新时间:2023-10-16

在他的演讲《现代模板元编程:纲要第一部分》中,Walter Brown 讨论了enable_if与 SFINAE 的相互作用。

在演讲中大约47:40,他被问到一个问题,我无法完全匹配他的回答。然而,这听起来的关键是,他说SFINAE与过载分辨率分开,恰好常用于函数的过载分辨率。

我理解他的回答的方式是,他也在说SFINAE有另一种用途。

除了过载分辨率之外,还可以在哪里应用 SFINAE?在听到他对这个问题的回答之前,我的理解是它唯一的用途是过载解决。

编辑:谈话在这里 https://www.youtube.com/watch?v=Am2is2QCvxY

如果您认为合适,可以根据参数禁用任何模板。

例如,可以想象矩阵类只能用算术类型实例化。 也就是说,我们希望允许实数和整数的矩阵,但不允许字符串的矩阵。 你可以这样做:

#include <type_traits>
template<typename T,
         typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
class Matrix
{
  // ...
};

现在,如果用户Matrix<double> m {}它将愉快地编译,但Matrix<std::string>会给出一个简单的错误消息,指出未定义此类类型。 这可能比矩阵类的某些内部没有为std::string操作数生成有效代码的错误消息页面更能帮助用户。

另一个用例是在模板的部分专用化中进行选择。 这可能是一个愚蠢的例子,但它可能会给你一个想法。 假设我们有一个模板,它采用两个类型参数,并希望专门用于它们都引用同一类型的情况。 但是,如果类型小于int,则专用化(出于某种模糊的原因)比主模板差,因此在这种情况下我们不希望它。

#include <iostream>
#include <type_traits>
template<typename T1, typename T2>
struct X
{
  void
  operator()()
  {
    std::cout << "I'm the primary template." << std::endl;
  }
};
template<typename T>
struct X<T, typename std::enable_if<(sizeof(T) >= sizeof(int)), T>::type>
{
  void
  operator()()
  {
    std::cout << "I'm the partial specialization." << std::endl;
  }
};
int
main()
{
  X<int, float> int_float {};  // primary template
  X<int, int> int_int {};      // partial specialization
  X<char, char> char_char {};  // primary template!
  int_float();
  int_int();
  char_char();
}

我的系统上的输出:

I'm the primary template.
I'm the partial specialization.
I'm the primary template.