使用三元运算符初始化auto&&时MSVC触发拷贝构造调用是否为编译器Bug?
关于MSVC编译含删除拷贝构造函数的三目表达式代码失败的问题
示例代码:
int main() { struct STR { STR() {} STR(const STR&) = delete; }; bool b = true; auto&& a0 = b ? STR{} : STR{}; }
现象说明
这段代码在最新版GCC和Clang中可正常编译,但在MSVC中编译失败,报错如下:
error C2280: 'main::STR::STR(const main::STR &)': attempting to reference a deleted function note: see declaration of 'main::STR::STR' note: 'main::STR::STR(const main::STR &)': function was explicitly deleted
结论
是的,这属于MSVC的编译器Bug。
原因解释
根据C++标准,三目运算符b ? STR{} : STR{}的两个操作数都是临时右值对象,且类型完全一致。此时表达式的结果应为右值,绑定到auto&&引用时,临时对象的生命周期会被直接延长,不需要触发拷贝构造函数。
GCC和Clang的处理符合标准逻辑,直接将临时对象绑定到引用;而MSVC错误地尝试调用被删除的拷贝构造函数来生成中间对象,这违背了C++标准的规定,属于编译器实现上的错误。
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

