← 模式

函数模板 SFINAE

1234567891011121314151617#include <type_traits> #include <limits> #include <cmath> template <typename T> typename std::enable_if<std::is_integral<T>::value, bool>::type equal(T lhs, T rhs) { return lhs == rhs; } template <typename T> typename std::enable_if<std::is_floating_point<T>::value, bool>::type equal(T lhs, T rhs) { return std::abs(lhs - rhs) < 0.0001; }

此模式采用 CC0 公共领域贡献 许可。

需要 c++11 或更新版本。

意图

根据模板参数,有条件地实例化一个函数模板。

描述

我们为 equal 函数模板提供了两种实现。

  1. 位于第 5-10 行的模板只会在 T 是整数类型时被实例化。
  2. 位于第 12-17 行的模板只会在 T 是浮点类型时被实例化。

我们已在第 6 行第 13 行使用了 std::enable_if 来强制实例化只在模板参数合适时才会成功。这依赖于“替换失败不是错误”(SFINAE)原则,该原则指出,对于某些特定的模板参数,实例化模板失败并不会导致错误,而只是简单地丢弃该实例化。

std::enable_if 的第二个模板参数(在本例中为 bool)是当第一个模板参数为 true 时,整个 std::enable_if<...>::type 所评估出的类型。这意味着 equal 函数的返回类型将是 bool

如果你只是想阻止一个模板针对某些模板参数被实例化,可以考虑改用 static_assert

贡献者

  • Joseph Mansfield

最后更新

2017年12月9日

来源

在 GitHub 上 Fork 此模式

分享