在不求值语境使用concept出现编译结果不一致,代码是否合法?
结论
这段代码不符合C++标准,Clang和MSVC的处理是正确的,GCC接受代码属于非标准的实现放宽,不具有通用性。
标准层面的解释
C++标准对概念的定义有明确约束:
- 概念的初始化器必须是约束表达式,约束表达式需要满足三个要求:是常量表达式、类型为
bool、无副作用。 - 当实例化
C<T>时,需要将模板参数代入概念的初始化表达式static_cast<T>(true),检查实例化结果是否符合约束表达式的要求,这一步是概念实例化的必经步骤,和使用它的语境是否为不求值语境无关。
两种实例化情况的区别
实例化
C<S>:static_cast<S>(true)本身是不合法的表达式(不存在从bool到自定义类型S的合法转换),这种情况属于「约束表达式实例化失败」,只会判定C<S>的约束不满足(值为false),但C<S>作为concept-id的类型依然是bool,因此decltype(C<S>)的用法完全合法,三家编译器的处理都符合标准。实例化
C<int>:static_cast<int>(true)是合法表达式,但它的类型是int而非要求的bool,直接违反了约束表达式的类型要求,属于硬编译错误,因此Clang和MSVC的报错是符合标准规定的。
GCC通过的原因
GCC对概念的实现做了非标准的放宽,没有强制检查实例化后约束表达式的类型是否为bool,属于实现层面的兼容扩展,不能作为代码符合标准的依据。
内容的提问来源于stack exchange,提问作者康桓瑋
相关产品推荐
相关产品推荐

