SFINAE超载分辨率?

时间:2015-01-15 22:20:41

标签: c++ sfinae

在他的演讲中,现代模板元编程:概要第一部分,Walter Brown用他的方式讨论了enable_if与SFINAE的互动。

在谈话中大约47:40,他被问到一个问题,我不能完全匹配他对所提问题的回答。然而,它的关键在于他说SFINAE与过载分辨率分开,恰好在函数的重载分辨率中常用。

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

在超载解决之外还可以应用SFINAE吗?在听到他对这个问题的回答之前,我的理解是它的使用了重载决策。

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

1 个答案:

答案 0 :(得分:1)

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

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

#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.