对SFINAE使用typename = enable_if_t<...>
和enable_if_t<...,bool> = true
有什么区别吗?因为我偶然发现了一个似乎是错误的错误,所以我特别要问:Compiler error with a fold expression in enable_if_t
所以我很好奇两者之间是否有实际差异。
答案 0 :(得分:4)
有一些细微的差别,但是两者都可以用于SFINAE。
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 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
答案 1 :(得分:1)
是的,有区别。第一个无效,而第二个有效。原因是默认模板参数不是函数签名的一部分。
通过“工作”,我的意思是第一个版本不会从候选过载集合中删除该函数,这通常是使用enable_if时希望达到的目标。
可以在此处找到示例(由@NathanOliver提供): http://coliru.stacked-crooked.com/a/a15a6f1d0eaff4ab