SFINAE是否依赖类型推导?

时间:2018-10-04 15:24:03

标签: c++ sfinae type-deduction template-deduction

我对cppreference.com中的以下引用感到困惑:

  

此规则适用于函数模板的重载解析:如果将推导类型替换为template参数失败,则会从重载集中放弃特化,而不会导致编译错误。

这是否意味着SFINAE如果没有类型推断就无法工作?例如,考虑以下代码:

template <typename T> std::true_type has_value_type_helper(typename T::value_type*);
template <typename> std::false_type has_value_type_helper(...);

template <typename T> inline constexpr bool has_value_type_v
   = decltype(has_value_type_helper<T>(nullptr))::value;

int main() {
   std::cout << has_value_type_v<int> << std::endl;
   std::cout << has_value_type_v<std::vector<int>> << std::endl;
}

它按预期工作,但据我所知,没有类型推断。在has_value_type_helper<T>(nullptr)中显式提供了模板参数。甚至可以以这种方式使用SFINAE吗?

2 个答案:

答案 0 :(得分:8)

  

甚至可以以这种方式使用SFINAE吗?

是的

替换是扣除过程的部分。显式提供模板参数不会消除对替换([temp.deduct]/2)的需要-而是替换(SFINAE中的S)失败不是错误([temp.deduct]/8)。

在这种情况下,当您向T显式提供has_value_type_helper时,我们仍然需要将T替换为参数T::value_type。那是在替换的直接上下文中,因此,如果替换失败-对于int这样的类型,它没有名为value_type的嵌套类型别名,那就是...这不是错误,我们只是将候选人从考虑中删除。我们还有另一个备份候选者,因此可以正常工作。

答案 1 :(得分:0)

这里没有“真实”类型推导,因为您直接指定了类型。但是sfinae仍在起作用,因为编译器会在实例化模板时推断出需要使用的内容。