不将std :: string嵌入异常的规则是否仍然适用于move构造函数?

卡米尔克

不久前,我听说我不应该创建具有std::string类型字段的异常类那就是Boost网站所说的基本原理是,std::string如果内存分配失败,则复制构造函数可以引发异常,并且如果在捕获当前处理的异常之前引发了异常,则程序将终止。

但是,它仍然在move构造函数世界中适用吗?抛出异常时,是否会使用move构造函数而不是copy构造函数?我是否正确理解在C ++ 11中不会发生内存分配,不存在异常的机会,并且std::string现在在异常类中绝对可以吗?

霍华德·辛南特

答案是:

是的,您仍然不想将a嵌入std::string到异常类型中。异常经常被复制,有时在您不知情的情况下。例如,在某些平台std::rethrow_exception上将复制异常(在某些平台上则不会)。

为了获得最佳实践,请保留复制构造函数noexcept

但是,一切并没有丢失。一个鲜为人知的事实是,C ++在标准中始终具有不可变的ref-counted字符串类型(具有非抛出复制构造函数),只是名称混淆。实际上有两个名字:

logic_error
runtime_error

这些类型的规范必须包含一个不变的引用计数的类似字符串的对象。好吧,不是完全不变的。您可以将字符串替换为赋值。但是您不能以其他方式在适当位置修改字符串。

我的建议是从这些类型之一派生,或者如果不能接受,则嵌入这些类型之一并将其视为不可变的ref-counted字符串类型:

#include <stdexcept>
#include <iostream>

class error1
    : public std::runtime_error
{
    using msg_ = std::runtime_error;
public:
    explicit error1(std::string const& msg)
        : msg_(msg)
    {}
};

class error2
{
    std::runtime_error msg_;
public:
    explicit error2(std::string const& msg)
        : msg_(msg)
    {}

    char const* what() const noexcept {return msg_.what();}
};

void
test_error1()
{
    try
    {
        throw error1("test1");
    }
    catch (error1 const& e)
    {
        std::cout << e.what() << '\n';
    }
}

void
test_error2()
{
    try
    {
        throw error2("test2");
    }
    catch (error2 const& e)
    {
        std::cout << e.what() << '\n';
    }
}

int
main()
{
    test_error1();
    test_error2();
}

std :: lib将为您处理所有的字符串处理和内存管理,并且您可以noexcept讨价还价进行复制:

static_assert(std::is_nothrow_copy_constructible<error1>{}, "");
static_assert(std::is_nothrow_copy_assignable   <error1>{}, "");
static_assert(std::is_nothrow_copy_constructible<error2>{}, "");
static_assert(std::is_nothrow_copy_assignable   <error2>{}, "");

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

std :: cout不将float打印为异常

来自分类Dev

为什么不将具有默认参数的函数传递给模板化的构造函数,并使用lambda将其存储为std :: function <void()>起作用?

来自分类Dev

适用于元素的“内容”规则是否等效?

来自分类Dev

如果禁用了异常,std :: vector <T>是否可以使用T的move构造函数?

来自分类Dev

std :: basic_string是否正式具有隐式生成的move构造函数?

来自分类Dev

std :: basic_string是否正式具有隐式生成的move构造函数?

来自分类Dev

为什么未调用std :: string move构造函数?

来自分类Dev

标识符规则是否适用于运算符重载功能?

来自分类Dev

经过身份验证的安全规则是否适用于Firebase匿名登录?

来自分类Dev

标识符规则是否适用于运算符重载功能?

来自分类Dev

std::bind 不适用于参考?

来自分类Dev

std :: bind不适用于std :: sort

来自分类Dev

重载的operator <<模板不适用于std :: list,尽管适用于std :: vector

来自分类Dev

在移动构造函数中使用std :: move

来自分类Dev

移动构造函数和std :: move混乱

来自分类Dev

从noexcept函数参数的构造函数引发的异常是否会立即导致对std :: terminate()的调用?

来自分类Dev

具有Rcpp :: interfaces的C ++接口不适用于返回std :: pair的函数

来自分类Dev

不将CSS应用于div

来自分类Dev

具有std :: string的文字类仅适用于模板专业化?

来自分类Dev

使用移动的std :: string的.data()成员不适用于小的字符串?

来自分类Dev

性状std :: convert :: From <String>不适用于hyper :: body :: Body

来自分类Dev

为什么不将函数视为命名类型?

来自分类Dev

熊猫:不将nan计入集合函数中

来自分类Dev

std :: pair:构造函数是否过于严格?

来自分类Dev

构造函数采用std :: string_view与std :: string并移动

来自分类Dev

std :: set_intersection适用于排序范围,[[]适用于未排序范围/容器

来自分类Dev

std :: cin适用于少量的行,但不适用于较大的行

来自分类Dev

为什么以下代码不调用std :: string的move构造函数?

来自分类Dev

为什么 std::string 的复制构造函数似乎比它的 move 副本更快?

Related 相关文章

  1. 1

    std :: cout不将float打印为异常

  2. 2

    为什么不将具有默认参数的函数传递给模板化的构造函数,并使用lambda将其存储为std :: function <void()>起作用?

  3. 3

    适用于元素的“内容”规则是否等效?

  4. 4

    如果禁用了异常,std :: vector <T>是否可以使用T的move构造函数?

  5. 5

    std :: basic_string是否正式具有隐式生成的move构造函数?

  6. 6

    std :: basic_string是否正式具有隐式生成的move构造函数?

  7. 7

    为什么未调用std :: string move构造函数?

  8. 8

    标识符规则是否适用于运算符重载功能?

  9. 9

    经过身份验证的安全规则是否适用于Firebase匿名登录?

  10. 10

    标识符规则是否适用于运算符重载功能?

  11. 11

    std::bind 不适用于参考?

  12. 12

    std :: bind不适用于std :: sort

  13. 13

    重载的operator <<模板不适用于std :: list,尽管适用于std :: vector

  14. 14

    在移动构造函数中使用std :: move

  15. 15

    移动构造函数和std :: move混乱

  16. 16

    从noexcept函数参数的构造函数引发的异常是否会立即导致对std :: terminate()的调用?

  17. 17

    具有Rcpp :: interfaces的C ++接口不适用于返回std :: pair的函数

  18. 18

    不将CSS应用于div

  19. 19

    具有std :: string的文字类仅适用于模板专业化?

  20. 20

    使用移动的std :: string的.data()成员不适用于小的字符串?

  21. 21

    性状std :: convert :: From <String>不适用于hyper :: body :: Body

  22. 22

    为什么不将函数视为命名类型?

  23. 23

    熊猫:不将nan计入集合函数中

  24. 24

    std :: pair:构造函数是否过于严格?

  25. 25

    构造函数采用std :: string_view与std :: string并移动

  26. 26

    std :: set_intersection适用于排序范围,[[]适用于未排序范围/容器

  27. 27

    std :: cin适用于少量的行,但不适用于较大的行

  28. 28

    为什么以下代码不调用std :: string的move构造函数?

  29. 29

    为什么 std::string 的复制构造函数似乎比它的 move 副本更快?

热门标签

归档