SFINAE 的 unspecializable std 模板是否格式错误?
Is SFINAE on unspecializable std templates ill-formed?
以下合法吗?
template<typename T>
std::enable_if_t<false, T> foo() {}
通常,我们有[temp.res]
The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template [...] and the template is not instantiated [...]
显然,无法为 foo
生成有效的特化...除非您认为 std::enable_if
可能被特化使得 type
呈现为 void
不管第一个 bool
参数。
struct S {};
template<bool B>
struct std::enable_if<B, S> : std::type_identity<void> {};
除了...您不能通过 [meta.rqmts]
对 std::enable_if
进行专业化
Unless otherwise specified, the behavior of a program that adds specializations for any of the templates specified in [meta] is undefined.
总而言之,如果您编写了模仿 std::enable_if
的 custom enable_if
,第一个片段是合法的。问题是禁止专业化 std::enable_if
是否使其成为非法?
此 post 的灵感来自 答案。当前形式改编自一个独立库的实现。
The question is whether the prohibition on specializing std::enable_if
makes it illegal?
我会说是的,确实如此。对于初学者来说,由于这种专业化会导致未定义的行为,我们可以完全忽略这种情况发生的可能性。那里违反了合同,因此进一步讨论合法性是没有意义的1.
现在,由于我们根本不必担心专业化,我们(作为试图确定 program/implementation 行为的人)可以依赖标准中描述的行为。 std::enable_if
的描述指定当其 bool 参数为 false
时它没有 ::type
成员。所以我们保证 std::enable_if<false, T>::type
总是病式的。
这导致不可避免地满足 [temp.res]/8 中的条件。 现在程序是格式错误的 NDR。
1 - 这毕竟是您引用的 [meta] 子句的目的。它允许假设有关标准库组件行为的事情。具体来说,以便实现可以围绕所述预期行为进行优化。
以下合法吗?
template<typename T>
std::enable_if_t<false, T> foo() {}
通常,我们有[temp.res]
The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template [...] and the template is not instantiated [...]
显然,无法为 foo
生成有效的特化...除非您认为 std::enable_if
可能被特化使得 type
呈现为 void
不管第一个 bool
参数。
struct S {};
template<bool B>
struct std::enable_if<B, S> : std::type_identity<void> {};
除了...您不能通过 [meta.rqmts]
对std::enable_if
进行专业化
Unless otherwise specified, the behavior of a program that adds specializations for any of the templates specified in [meta] is undefined.
总而言之,如果您编写了模仿 std::enable_if
的 custom enable_if
,第一个片段是合法的。问题是禁止专业化 std::enable_if
是否使其成为非法?
此 post 的灵感来自
The question is whether the prohibition on specializing
std::enable_if
makes it illegal?
我会说是的,确实如此。对于初学者来说,由于这种专业化会导致未定义的行为,我们可以完全忽略这种情况发生的可能性。那里违反了合同,因此进一步讨论合法性是没有意义的1.
现在,由于我们根本不必担心专业化,我们(作为试图确定 program/implementation 行为的人)可以依赖标准中描述的行为。 std::enable_if
的描述指定当其 bool 参数为 false
时它没有 ::type
成员。所以我们保证 std::enable_if<false, T>::type
总是病式的。
这导致不可避免地满足 [temp.res]/8 中的条件。 现在程序是格式错误的 NDR。
1 - 这毕竟是您引用的 [meta] 子句的目的。它允许假设有关标准库组件行为的事情。具体来说,以便实现可以围绕所述预期行为进行优化。