SFINAE在不可特化的std模板上是格式错误的吗?

以下是否合法?

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

通常,我们有[temp.res]

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

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

显然,不能为foo...生成有效的特化,除非您认为它std::enable_if可能被特type化为void无论第一个bool参数如何都存在。

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

除非......你不能专注std::enable_if通过[meta.rqmts]

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

总而言之,如果您编写了一个模仿的自定义enable_ifstd::enable_if,则第一个片段是合法的。问题是禁止专攻是否std::enable_if使其违法?

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

回答

问题是禁止专攻是否std::enable_if使其违法?

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

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

这导致不可避免地满足 [temp.res]/8 中的标准。而现在的方案是形成不良的NDR。



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


以上是SFINAE在不可特化的std模板上是格式错误的吗?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>