C++私有继承场景下三目运算符类型判定哪个编译器符合标准?
问题结论
Clang的实现符合C++标准,GCC此处存在合规性缺陷
规则与场景分析
C++条件(三目)运算符E1 ? E2 : E3的类型确定规则中,当E2和E3为不同类型时,若其中一个操作数可被合法且唯一转换为另一个的类型,则运算符的结果类型为后者。
测试代码如下:
class A; struct B { B() {} B(const A &) {} }; class A : B {}; int main() { void( true ? B{} : A{} ); }
核心逻辑判断:
- A私有继承自B,因此A到B的派生类向上转型的标准转换是不可访问的,属于无效转换,在转换序列决议阶段会被直接排除。
- 剩余唯一可行的转换路径是
B::B(const A&)提供的用户定义转换,可将A类型右值合法转换为B类型。 - 不存在B到A的任何可行转换路径,因此三目运算符的结果类型唯一确定为B,第三个操作数会通过上述构造函数完成转换,整个表达式合法。
GCC抛出的错误error: 'B' is an inaccessible base of 'A',本质是在转换序列排序阶段错误地将不可访问的派生到基类转换纳入考量,没有先过滤掉不满足访问性要求的无效转换路径,不符合C++标准的要求。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

