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

C++中带非const引用构造函数的类型能否按值捕获异常?

这属于MSVC的错误诊断,在C++17及更高版本标准下,GCC和Clang的编译行为是符合标准的,示例代码本身合法。

示例代码如下:

struct A {
    A() {}
    A(A&) {}
    A(const A&) = delete;
};

int main() {
    try {
        throw A{};
    }
    catch( A ) {
    }
}

合法性解释

  • throw 阶段的强制复制消除:C17起标准规定了强制复制消除规则,当throw的操作数是纯右值时,编译器必须直接在异常专用存储区构造异常对象,完全跳过拷贝/移动构造函数的调用。因此这一步不需要A的拷贝构造参与,本身合法。如果是C17之前的标准,复制消除属于可选优化,此时throw A{}需要将纯右值A{}拷贝到异常存储,而纯右值无法绑定到非const左值引用A&,代码才是不合法的。
  • 按值捕获的初始化逻辑:catch子句的形参会由异常对象进行拷贝初始化,异常对象本身是非常量左值,A(A&)构造函数可以完美匹配非常量左值的引用绑定,整个初始化过程完全合法,不需要调用被删除的A(const A&)构造函数。

MSVC的报错逻辑存在缺陷,它默认要求异常类型必须具备可访问的const左值引用拷贝构造函数,没有考虑到非const拷贝构造函数匹配的合法场景,不符合C++17及之后的标准规定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:36:07