`typename = enable_if_t<...>` 和 `enable_if_t<...,bool> = true` 之间的区别

lig*_*ulb 1 c++ templates enable-if

使用typename = enable_if_t<...>enable_if_t<...,bool> = true用于 SFINAE之间有什么区别吗?我特别问,因为我偶然发现了一个错误:编译器错误,在 enable_if_t 中有一个折叠表达式

所以我很好奇两者之间是否有任何实际差异。

Jar*_*d42 5

有细微差别,但两者都可用于 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()
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

另一个问题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
Run Code Online (Sandbox Code Playgroud)