You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20 Concepts约束规范化:Concept B是否导致程序非法?

C++20概念规范化中B的合法性解析

来自C++20标准(ISO/IEC 14882:2020)第13.5.4节([temp.constr.normal])第1段:
concept-id C<A1, A2, ..., An>的范式是将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的约束表达式规范化是有效的,结果为T::value(映射关系T -> U*)或true(空映射),尽管对于指针类型T,表达式T::value是非法的。C的约束表达式规范化会导致程序非法,因为参数映射中会形成无效类型V&*。

疑问点

我理解C会导致程序非法及其原因,但不清楚B是否会导致程序非法。文中指出B的规范化有效,但同时说明针对指针类型的T::value表达式非法。这是否意味着仅规范化过程有效,后续检查T::value时程序才会非法?还是程序始终合法,T::value的检查被跳过/规避?

解答

首先明确:仅仅定义B这个concept模板本身是合法的,核心原因在于标准中提到的“代入产生无效类型或表达式导致程序非法”,特指规范化阶段的代入操作,而非后续约束检查阶段的代入。

  • B的规范化过程合法:
    规范化B时,是把U*代入A的模板参数T,建立映射T→U*。这个过程中U*是合法的类型(无论U是什么类型,指针类型本身都是有效的),所以规范化步骤没有产生无效类型或表达式,因此B的规范化是有效的,程序定义B的行为本身不非法。

  • 后续约束检查的逻辑短路:
    当实际使用B<X>(比如B<int>)时,需要检查A<int*>的约束表达式T::value || true(此时T是int*)。由于逻辑或||的短路求值特性,只要右侧的true为真,编译器不需要计算左侧的T::value(也就是int*::value),因此不会触发这个非法表达式的检查。这就意味着,只要约束表达式因为短路特性不需要评估非法的部分,程序在该使用场景下就是合法的。

  • 如果没有短路特性的情况:
    假设A的约束表达式改为T::value && true,那么当使用B<int>时,编译器必须评估int*::value,此时才会触发程序非法(因为指针类型没有value静态成员)。但这种情况属于约束检查阶段的问题,而非规范化阶段的问题,和B本身的合法性无关。

内容的提问来源于stack exchange,提问作者J L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:20:37