返回类型与模板参数中的 SFINAE:比较
在 C 中,替换失败不是错误 (SFINAE) 习惯用法允许有条件基于类型的可用性的编译。但是,当放置在模板中的不同位置时,其行为可能会有所不同。
模板参数中的 SFINAE
在下面的代码中,SFINAE 用作模板参数启用或禁用特定模板函数重载。
template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> auto foo(T) -> void { /* ... */ } template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type> auto foo(T) -> void { /* ... */ }
在这种情况下,SFINAE 应用于第二个模板参数,即实际上是一个占位符。尝试调用 foo(3.4) 时会发生错误,因为第二个模板函数声明带有 std::enable_if<:is_floating_point>::value> 。未定义,导致缺少重载。
返回类型中的 SFINAE
相反,以下代码在返回类型中使用 SFINAE:
template<typename T> auto foo(T) -> typename std::enable_if<std::is_integral<T>::value>::type { /* ... */ } template<typename T> auto foo(T) -> typename std::enable_if<std::is_floating_point<T>::value>::type { /* ... */ }
在这种情况下,SFINAE 应用于返回类型,这允许编译器根据提供的参数区分两个模板函数type.
为什么会有差异?
行为上的差异源于默认模板参数的使用。在第一个示例中,第二个模板参数默认为 typename std::enable_if<:is_integral>::value>::type,这使得模板函数声明等效。
但是,在第二个示例,返回类型在表达式中使用 SFINAE,它是函数签名的一部分。这确保了模板函数具有不同的签名,并允许 SFINAE 按预期工作。
以上是C 中的 SFINAE:模板参数与返回类型 – 有什么区别?的详细内容。更多信息请关注PHP中文网其他相关文章!