【问题标题】:Is SFINAE on unspecializable std templates ill-formed?非专业化标准模板上的 SFINAE 格式不正确吗?
【发布时间】:2023-03-29 08:42:01
【问题描述】:

以下合法吗?

template<typename T>
std::enable_if_t<false, T> foo() {}

通常,我们有[temp.res]

程序格式错误,不需要诊断,如果:

  1. 无法为模板生成有效的特化 [...] 并且模板未实例化 [...]

显然,不能为 foo... 生成有效的特化...除非您认为 std::enable_if 可能是特化的,使得 typevoid 的形式出现,而不管第一个 bool 参数如何。

struct S {};
template<bool B>
struct std::enable_if<B, S> : std::type_identity<void> {};

除了...您不能通过 [meta.rqmts] 专门化 std::enable_if

除非另有说明,否则为 [meta] 中指定的任何模板添加特化的程序的行为是未定义的。

总而言之,如果你写了一个模仿std::enable_ifcustom enable_if,那么第一个sn-p 是合法的。问题是禁止专门化std::enable_if是否使其非法?

这篇文章的灵感来自this 的回答。当前的形式改编自一个独立库的实现。

【问题讨论】:

  • 我看不出用户定义的enable_if 会有什么帮助。 enable_if 取决于一个值,而不是一个类型,因此您只能将其专门用于 truefalse
  • @NathanOliver 自定义enable_if 的第二个参数仍然是一个可以专门化的模板参数,就像在第二个sn-p 中一样。只是我们通常不会那样想。
  • 啊哈。我想你可以这样做,但是你并没有真正按照你所说的去做。 enable_if&lt;false, T&gt; 应该评估为无,因此它可以正常工作。听起来你真正需要的是std::conditionial,而不是std::enable_if
  • 如果你不被允许做一件事,那么做你不被允许做的事情就是非法的。从那时起,您可能做了什么其他已不再重要。我不明白问题是什么。
  • standard 中所指定,std::enable_if 不能从编译器获得虚拟特化以具有(无法访问的)有效类型。

标签: c++ language-lawyer


【解决方案1】:

问题是禁止专门化std::enable_if是否使其非法?

我会说是的,确实如此。首先,由于这种专业化会导致未定义的行为,我们可以完全忽略这种情况发生的可能性。那里违反了合同,因此进一步讨论合法性没有实际意义1

现在,由于我们根本不必担心专业化,我们(作为试图确定程序/实现行为的人)可以依赖标准中描述的行为。 std::enable_if 的描述指定当其 bool 参数为 false 时,它没有 ::type 成员。所以我们保证std::enable_if&lt;false, T&gt;::type 总是格式错误的。

这导致不可避免地满足 [temp.res]/8 中的标准。 现在该程序是格式错误的 NDR。


1 - 这毕竟是你引用的 [meta] 子句的目的。它允许对标准库组件的行为进行假设。具体来说,以便实现可以围绕所述预期行为进行优化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-21
    • 2018-09-28
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 2020-10-13
    相关资源
    最近更新 更多