这是 C++20 标准 (ISO/IEC 14882:2020) 第 13.5.4 节 ([温度.施工.正常] https://eel.is/c++draft/temp.constr.normal),第 1 段(强调我的):
概念 ID C 的范式是约束表达式在每个原子约束的参数映射中用 A1 , A2 , ..., An 替换 C 各自的模板参数后,得到 C 的结果。如果任何此类替换导致无效类型或表达式,则该程序格式错误;无需诊断。
template<typename T> concept A = T::value || true;
template<typename U> concept B = A<U*>;
template<typename V> concept C = B<V&>;
B 的标准化约束表达式 is valid并导致T::value
(与映射T -> U*
) V true
(使用空映射),尽管表达式T::value
being 不规范的对于指针类型T
。 C 的标准化约束表达式导致程序格式错误,因为它会形成无效类型V&*
在参数映射中。
我知道 C 会使程序格式错误(以及原因)。然而,我不清楚 B 是否会导致程序格式错误。文本指出 B 的归一化是有效的,但同时也指出表达式T::value
由于该指针类型(我理解)而格式不正确。这是否意味着只有过程的规范化部分有效,但程序本身在后期检查时格式不正确T::value
?或者该程序在任何情况下都有效并且检查T::value
以某种方式跳过/避免?
我查过Godbolt的编译器资源管理器 https://godbolt.org/z/YnTe54P9eGCC 和 Clang 似乎都对此表示满意。尽管如此,由于标准说“无需诊断”,这并没有多大帮助。
概念 B 是有效的,因为您可以将指针传递给概念 A。在 A 本身内部,指针无法访问::value
但是,根据规范,[温度构造原子] https://eel.is/c++draft/temp.constr#atomic-3.sentence-2,不会被视为错误,而是被视为false
,那么|| true
在概念 A 上将使整个表达式true
.
请注意,如果我们将 int& 传递给概念 B,那么我们的代码将是 IFNDR,因为 B 会尝试将无效类型传递给 A (int&*
).
概念 C 本身就是 IFNDR,因为它传递了对 B 的引用,B 尝试将指向该引用的指针传递给 A,然后再次传递一个V&*
类型无效。
试图评估一个格式错误,无需诊断表达使用static_assert
不一定有助于回答表达式是否有效的问题,因为编译器不需要失败static_assert on an 格式错误,无需诊断表达 https://stackoverflow.com/questions/75443227/static-assert-on-an-ill-formed-no-diagnostic-required-expression.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)