SFINAE是否依赖于类型扣除?

Dan*_*ica 3 c++ sfinae type-deduction template-argument-deduction

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

此规则适用于函数模板的重载解析期间:当替换推导类型的模板参数失败时,将从重载集中丢弃特化而不是导致编译错误.

这是否意味着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;
}
Run Code Online (Sandbox Code Playgroud)

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

Bar*_*rry 8

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

是.

替换是扣除过程的一部分.明确提供模板参数并不能消除替换的需要([temp.deduct]/2) - 而且它是替换(SFINAE中的S)失败并非错误([temp.deduct]/8).

在这种情况下,当您明确提供Thas_value_type_helper,我们仍然需要替换T参数T::value_type.这是在替换的直接上下文中,所以如果那个替换失败 - 对于int那些没有命名的嵌套类型别名的类型value_type- 它是......而不是错误,我们只是从考虑中删除候选.我们有另一个备用候选者,所以这很好.