【问题标题】:Difference between `typename = enable_if_t<...>` and `enable_if_t<...,bool> = true``typename = enable_if_t<...>` 和 `enable_if_t<...,bool> = true` 之间的区别
【发布时间】:2019-07-10 21:05:10
【问题描述】:

在 SFINAE 中使用 typename = enable_if_t&lt;...&gt;enable_if_t&lt;...,bool&gt; = true 有什么区别吗?我特别问,因为我偶然发现了一个看起来像错误的东西:Compiler error with a fold expression in enable_if_t

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

【问题讨论】:

标签: c++ templates enable-if


【解决方案1】:

有细微差别,但两者都可用于 SFINAE。

typename = enable_if_t&lt;...&gt; 表单不允许“简单”重载:

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&lt;cond, bool&gt; = 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&lt;...&gt; 的另一个问题是使用可能被劫持:

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

【讨论】:

    【解决方案2】:

    是的,有区别。第一个不起作用,而第二个起作用。原因是默认模板参数不是函数签名的一部分。

    我所说的“工作”是指第一个版本不会从候选重载集中删除函数,这通常是使用 enable_if 时所期望的目标。

    可以在这里找到一个例子(@NathanOliver 提供): http://coliru.stacked-crooked.com/a/a15a6f1d0eaff4ab

    【讨论】:

    • @lightxbulb 在某种意义上它不起作用,因为它不会从一组重载候选者中删除一个函数。
    • 怎么不呢? AFAIK 仅当您尝试使用多个函数模板重载函数时它才不起作用。
    • @NathanOliver 我已经添加了一些澄清声明,这正是我的意思,这就是(至少根据我的经验)使用 enable_if 的原因。
    • 我认为您可能需要进一步澄清一下。它在重载的上下文中工作here。只有当您尝试添加多个模板重载时才会失败,例如 this
    • @SergeyA 我认为这是一个奇怪的观点,似乎与标准相矛盾。见 [temp.deduct]/6-8, [temp.over]/1。扣除被认为是失败的,因此没有候选人。
    猜你喜欢
    • 2020-09-30
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    相关资源
    最近更新 更多