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

条件运算符:不同编译器隐式转换序列不一致问题

条件运算符中基类与派生类对象的编译行为疑问

这是问题《conditional operator expression with base and const derived class doesn't compile, why?》的后续,核心场景为cond ? [cv] T1() : [cv] T2(),其中T2公有继承自T1。

在推导该表达式的类型时,似乎需要依赖派生类对象到基类对象的隐式转换序列,但cppreference的隐式转换规则仅覆盖了派生类指针/引用到基类指针/引用的转换,未明确提及对象本身的转换逻辑。

原问题使用的类型十分简单:

struct X {};
struct Y : X {};

这类类型会生成隐式默认的移动和拷贝构造函数,可能构成隐式转换序列。为验证该假设,我们显式声明这些构造函数以打破转换序列:

#include <iostream>

struct X {
    X() = default;
    explicit X(X const &) { std::cout << "copy to base\n"; }
    explicit X(X &&) { std::cout << "move to base\n"; }
    virtual ~X() = default;
};
struct Y : X {
    Y() = default;
    Y(Y const &y) : X(y) { std::cout << "copy to derived\n"; }
    Y(Y &&) { std::cout << "move to derived\n"; }
    virtual ~Y() = default;
};

int main() { true ? Y() : X(); }

测试不同explicit关键字组合后,得到如下结果:

explicit修饰情况gccclangmsvc
无move to basemove to basemove to base
仅修饰移动构造move to base(预期为copy)copy to basemove to base(预期为copy)
仅修饰拷贝构造move to basemove to basemove to base
两者都修饰move to base(预期为error)errorerror

我的预期逻辑是:若基类存在隐式移动构造函数,则使用它构成转换序列;否则尝试使用隐式拷贝构造函数;若两者都不存在,则无合法的隐式转换序列。

为何不同编译器的输出存在差异,且部分结果与预期不符?

注:条件运算符的使用对问题至关重要,替换为函数调用时结果更符合预期(除MSVC外):

void foo(X) {};
int main() { foo(Y()); }

此场景下仅MSVC行为异常,始终使用移动运算符,推测是MSVC的bug。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 17:15:02