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

使用纯右值直接初始化:MSVC存在编译器Bug吗?

这是MSVC的编译器Bug吗?

是的,这属于MSVC的编译器Bug,符合C++17标准的这段代码应当被正常编译。

先看涉及的代码:

struct S
{
    S(int, double) {}
    explicit S(const S&) {}
    explicit S(S&&) {}
};

void i_take_an_S(S s) {}

S i_return_an_S() { return S{ 4, 2.0 }; }

int main()
{
    i_take_an_S(i_return_an_S());
}

编译器表现差异

  • 启用-std=c++17选项时,GCC和Clang均可正常编译这段代码
  • MSVC启用/std:c++17选项时,会报出错误:

    "error C2664: 'void i_take_an_S(S)': cannot convert argument 1 from 'S' to 'S'"

    "Constructor for struct 'S' is declared 'explicit'."

C++17标准规则分析

C++17强制要求编译器执行纯右值的拷贝消除,同时在函数参数初始化场景中:当实参是类类型的纯右值时,编译器必须直接将该纯右值的对象构造到目标形参的内存位置,此过程不会触发任何拷贝或移动构造函数——也就是说,编译器根本不需要考虑这些构造函数的存在,自然也不受explicit修饰符的影响。

回到这段代码:i_return_an_S()返回的是S类型的纯右值,调用i_take_an_S时,编译器应当直接把这个纯右值构造到形参s的内存空间中,完全不需要尝试调用explicit的拷贝/移动构造函数。MSVC错误地触发了对拷贝/移动构造函数的检查,进而因为explicit修饰符报错,这明显违反了C++17的标准规定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:45:51