SFINAE 是否依赖于类型推导?
Does SFINAE depend on type deduction?
我对 cppreference.com 中的以下引用感到困惑:
This rule applies during overload resolution of function templates: When substituting the deduced type for the template parameter fails, the specialization is discarded from the overload set instead of causing a compile error.
这是否意味着没有类型推导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也可以这样用吗?
这里没有"real"类型推导,因为你直接指定了类型。但是 sfinae 仍然在这里工作,因为编译器在实例化模板时推断出它需要使用什么。
Can even SFINAE be used this way?
是的。
代入是演绎过程的部分。显式提供模板参数并不能避免替换的需要 ([temp.deduct]/2) - and it's the substitution (the S in SFINAE) failure that is not an error ([temp.deduct]/8)。
在这种情况下,当您显式提供T
给has_value_type_helper
时,我们仍然需要将T
代入参数T::value_type
。那是在替换的直接上下文中,所以如果替换失败 - 对于像 int
这样没有名为 value_type
的嵌套类型别名的类型 - 它是......不是错误,我们只是将候选人从考虑中移除。我们有另一个备用候选人,所以这很好用。
我对 cppreference.com 中的以下引用感到困惑:
This rule applies during overload resolution of function templates: When substituting the deduced type for the template parameter fails, the specialization is discarded from the overload set instead of causing a compile error.
这是否意味着没有类型推导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也可以这样用吗?
这里没有"real"类型推导,因为你直接指定了类型。但是 sfinae 仍然在这里工作,因为编译器在实例化模板时推断出它需要使用什么。
Can even SFINAE be used this way?
是的。
代入是演绎过程的部分。显式提供模板参数并不能避免替换的需要 ([temp.deduct]/2) - and it's the substitution (the S in SFINAE) failure that is not an error ([temp.deduct]/8)。
在这种情况下,当您显式提供T
给has_value_type_helper
时,我们仍然需要将T
代入参数T::value_type
。那是在替换的直接上下文中,所以如果替换失败 - 对于像 int
这样没有名为 value_type
的嵌套类型别名的类型 - 它是......不是错误,我们只是将候选人从考虑中移除。我们有另一个备用候选人,所以这很好用。