`typename = enable_if_t<...>` 和 `enable_if_t<...,bool> = true` 的区别
Difference between `typename = enable_if_t<...>` and `enable_if_t<...,bool> = true`
在 SFINAE 中使用 typename = enable_if_t<...>
和 enable_if_t<...,bool> = true
有什么区别吗?我特意询问,因为我偶然发现了一个看起来像错误的东西:Compiler error with a fold expression in enable_if_t
所以我很好奇两者之间是否有任何实际差异
是的,有区别。第一个不起作用,而第二个起作用。原因是默认模板参数不是函数签名的一部分。
"work" 我的意思是第一个版本不会从候选重载集中删除函数,这通常是使用 enable_if 时的预期目标。
可以在此处找到示例(@NathanOliver 提供):
http://coliru.stacked-crooked.com/a/a15a6f1d0eaff4ab
存在细微差别,但都可用于 SFINAE。
typename = enable_if_t<...>
表单不允许 "simple" 重载:
template <typename T, typename = enable_if_t<cond<T>::value>>
void foo();
template <typename T, typename = enable_if_t<!cond<T>::value>>
void foo(); // Error: redeclaration of same function as default are not part of signature
// Both are just template <typename, typename> void foo()
enable_if_t<cond, bool> = true
不受此影响:
template <typename T, enable_if_t<cond<T>::value, bool> = true>
void foo();
template <typename T, enable_if_t<!cond<T>::value, bool> = true>
void foo();
typename = enable_if_t<...>
的另一个问题是使用可能被劫持:
template <typename T, typename = enable_if_t<cond<T>::value>>
void foo();
template <typename T, typename = enable_if_t<cond<T>::value>>
void bar(T);
foo<int>(); // Regular usage, SFINAE occurs
bar(42); // Regular usage, SFINAE occurs
bar<int>(42); // Possible usage, SFINAE still occurs
// But
foo<int, void>(); // No substitution fails here, so no SFINAE
bar<int, void>(42); // No substitution fails here, so no SFINAE
在 SFINAE 中使用 typename = enable_if_t<...>
和 enable_if_t<...,bool> = true
有什么区别吗?我特意询问,因为我偶然发现了一个看起来像错误的东西:Compiler error with a fold expression in enable_if_t
所以我很好奇两者之间是否有任何实际差异
是的,有区别。第一个不起作用,而第二个起作用。原因是默认模板参数不是函数签名的一部分。
"work" 我的意思是第一个版本不会从候选重载集中删除函数,这通常是使用 enable_if 时的预期目标。
可以在此处找到示例(@NathanOliver 提供): http://coliru.stacked-crooked.com/a/a15a6f1d0eaff4ab
存在细微差别,但都可用于 SFINAE。
typename = enable_if_t<...>
表单不允许 "simple" 重载:
template <typename T, typename = enable_if_t<cond<T>::value>>
void foo();
template <typename T, typename = enable_if_t<!cond<T>::value>>
void foo(); // Error: redeclaration of same function as default are not part of signature
// Both are just template <typename, typename> void foo()
enable_if_t<cond, bool> = true
不受此影响:
template <typename T, enable_if_t<cond<T>::value, bool> = true>
void foo();
template <typename T, enable_if_t<!cond<T>::value, bool> = true>
void foo();
typename = enable_if_t<...>
的另一个问题是使用可能被劫持:
template <typename T, typename = enable_if_t<cond<T>::value>>
void foo();
template <typename T, typename = enable_if_t<cond<T>::value>>
void bar(T);
foo<int>(); // Regular usage, SFINAE occurs
bar(42); // Regular usage, SFINAE occurs
bar<int>(42); // Possible usage, SFINAE still occurs
// But
foo<int, void>(); // No substitution fails here, so no SFINAE
bar<int, void>(42); // No substitution fails here, so no SFINAE