抛出异常时不会调用移动构造函数

2023-12-10

我有一个累积当前异常的变量,并且需要在引发当前异常时进行清理(以便不会再次报告相同的错误)。问题是throw std::move(ex);不调用移动构造函数(这会清理ex),而是调用复制构造函数(以便ex也保留已经抛出的错误)。 MVCE 如下:

#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;

class ThrowMoveTest : exception
{
public:
    ThrowMoveTest(const string& what)
    {
        _what = what;
    }
    ThrowMoveTest(const ThrowMoveTest& fellow)
    {
        cout << "Copy " << what() << endl;
        _what = fellow._what;
    }
    ThrowMoveTest(ThrowMoveTest&& fellow)
    {
        cout << "Move " << what() << endl;
        _what = std::move(fellow._what);
    }
    virtual const char* what() const override
    {
        return _what.c_str();
    }
private:
    mutable string _what;
};

int main()
{
    try
    {
        ThrowMoveTest tmt1("Test1");
        throw move(tmt1);
    }
    catch (const ThrowMoveTest& ex)
    {
        cout << "Caught " << ex.what() << endl;
    }
    return 0;
}

我正在使用 MSVC++2013 Update 5。

我是否做错了什么,因此移动构造函数不会被调用?是否可以抛出异常,以便 C++ 中用于异常存储的临时对象是移动构造的,而不是从原始对象复制构造的?

我试图避免的是双重复制:构建一个副本tmt1,然后清洁原件,然后使用副本throw语句,这将构造另一个副本用于临时存储。

编辑:上面的代码示例在 MSVC++2013 Update 5 上给出以下输出

Copy
Caught Test1

虽然预期输出是

Move
Caught Test1

EDIT2:提交了编译器错误报告https://connect.microsoft.com/VisualStudio/feedback/details/1829824


这是一个 MSVC 错误。来自[例外.抛出]:

抛出异常会复制初始化 (8.5, 12.8) 一个临时对象,称为异常对象.

这意味着我们这样做:

ThrowMoveTest __exception_object = move(tmt1);

这肯定应该调用移动构造函数。


请注意,move这是不必要的,也是有害的。 [class.copy] 规定可以省略复制/移动构造

— in a 抛出表达式(5.17),当操作数是非易失性自动对象的名称时(除了 函数或 catch 子句参数),其范围不超出最内层的末尾 封闭 try 块(如果有),从操作数到异常的复制/移动操作 可以通过将自动对象直接构造到异常对象中来省略对象(15.1)

就这么简单throw tmt1;会允许tmt1直接构造到异常对象中。尽管 gcc 和 clang 都没有这样做。

即使复制/移动没有被删除:

当满足复制/移动操作的省略标准,但不满足异常声明时,并且 要复制的对象由左值[...]重载决策指定 首先执行为副本选择构造函数的操作,就好像该对象是由右值指定的一样。

So throw tmt1;仍然会移动构造异常对象。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

抛出异常时不会调用移动构造函数 的相关文章

随机推荐

  • Tor Stem - 前往俄罗斯,有爱情联系问题

    我正在尝试获取带着爱去俄罗斯教程来自 Stem 项目的工作 from io import StringIO import socket import urllib3 import time import socks SocksiPy mod
  • 让方法运行或引发异常的 Python 装饰器

    我需要一个装饰器 它接受一个参数并检查 基于一些简单的逻辑 是否应该允许该方法运行或引发异常 class One obj trend trend myDecorator self trend def click button self cl
  • 在 Sankey 工具提示中显示边缘信息

    我正在使用 networkD3 包中的 sankeyNetwork 来创建可视化 我想为每条边分配一个名称 ID 以便它出现在工具提示中 这可以通过 sankeyNetwork 或 networkD3 包中的任何其他函数来完成吗 这在技术上
  • php、jquery 只有第一个 id 工作正常

    我在 php 中有以下代码 代码经过编辑以便于理解 while row mysql fetch array biznis div div img src social images avatar empty avatar full jpg
  • 如何将所有网络流量重定向到特定页面?

    有没有办法将我网站的所有流量重定向到特定页面 我的免费主机确实支持 PHP 不确定这是否适合于此 谢谢 如果您的主机基于 Apache 并支持模组重写 用那个 例如 WordPress 典型的重写 将对不存在的文件 文件夹的请求重定向到in
  • std::数组的向量

    以下声明通过编译检查 int arr 3 vector
  • 如何将 Perlin 噪声值标准化到范围 [0, 1]?

    我正在使用 numpy 数组来保存柏林噪声值 有人告诉我 二维数组中的柏林噪声值分别在 0 7 0 7 范围内 但这似乎并非如此 至少对于凯斯曼来说不是 noise 库 当我调整八度 持久性和空白度的参数时 我会使用不同的库 但我找不到任何
  • Powerpoint VBA - 更改配色方案

    我需要通过 VBA 代码将演示文稿的配色方案更改为 Office 2007 2010 我怎样才能做到这一点 我尝试了类似下面的方法 但似乎不起作用 ActivePresentation ColorSchemes Add ActivePres
  • 如何在 laravel 5.3 中显示当前日期的日期名称?

    我想在 laravel 5 3 中打印当前日期的名称 我可以通过以下方式获取当前日期 上面的代码打印 25 但我希望它打印星期四 我应该怎么做 Try this
  • 有没有办法在密码文本模式下设置 ASP.NET 文本框密码字符?

    我希望当用户输入文本时 它应该显示 而不是一个简单的星号 有没有办法 在win forms的TextBox中有一个属性PasswordChar 它在web中有何相似之处 不 这是特定于浏览器的 也许你可以用 javascript 来伪造这个
  • 如何在 Delphi XE 中国际化我的应用程序?

    我正在使用 Delphi 中包含的翻译管理器 xe8 但在旧版本中应该相同 我转到 Projet gt 语言 gt 添加 选择英语 然后我翻译文本 这里是按钮 我全部更新并编译 我得到了 exe 和 enu 文件 它是法语的 当我转到 Pr
  • matlab中的KNN算法

    我正在研究拇指识别系统 我需要实现 KNN 算法来对我的图像进行分类 根据this 它只有 2 个测量值 通过这些测量值计算找到最近邻居的距离 但在我的例子中 我有 400 张 25 X 42 的图像 其中 200 个用于训练 200 个用
  • Spring Boot REST · @Constraint 用于删除?

    我正在开发一个使用 Spring Boot REST HATEOAS Hibernate 和 PostgreSQL 的系统后端 为了验证 我开始使用以下类extend org springframework validation Valid
  • LibGDX 移动旋转相机

    我在使用 LibGDX 构建的应用程序中遇到了一种情况 我需要相机能够旋转 并且可以由用户移动 并且能够缩放 我的相机移动和缩放相机的控件工作得很好 但是 当相机旋转时 相机会根据该旋转移动 例如 如果相机向左旋转 45 度 并且用户向右拖
  • 张量流/keras中输入的自相关

    我有一个一维输入信号 我想计算自相关作为神经网络的一部分 以便在网络内部进一步使用 我需要对输入与输入本身进行卷积 在 keras 自定义层 张量流中执行卷积 我们需要以下参数data shape is batch in height in
  • data.frame 中每组的平均值[重复]

    这个问题在这里已经有答案了 我有一个data frame我需要计算每组的平均值 即每Month 以下 Name Month Rate1 Rate2 Aira 1 12 23 Aira 2 18 73 Aira 3 19 45 Ben 1 5
  • 使用 javascript 以管理员身份运行批处理的简单方法

    我想导出一种简单可靠的方法来自动提升正在运行的批处理 而无需使用其他线程中建议的额外 VBS 文件或提升的快捷方式 通过 javascript 从批处理中调用 UAC 对话框可确保代码简短 当在对话框中选择 是 时 下面的脚本会自动将用户正
  • 多维数组中的多个文件上传

    我有一个 php 表单 行数未知 用户可以在其中上传文件 为此 我使用二维数组
  • 如何使用java读取https页面内容? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 如何使用java读取https页面内容 以下是检索 页面内容 的示例https maven apache org guides mini guide repository ssl
  • 抛出异常时不会调用移动构造函数

    我有一个累积当前异常的变量 并且需要在引发当前异常时进行清理 以便不会再次报告相同的错误 问题是throw std move ex 不调用移动构造函数 这会清理ex 而是调用复制构造函数 以便ex也保留已经抛出的错误 MVCE 如下 inc