转换到C ++ 11,其中析构函数被隐含地声明为noexcept [英] Transitioning to C++11 where destructors are implicitly declared with noexcept

查看:185
本文介绍了转换到C ++ 11,其中析构函数被隐含地声明为noexcept的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 11中,没有任何异常规范的析构函数被隐含地声明为 noexcept ,这是C ++ 03中的一个变化。因此,C ++ 03中用于抛出析构函数的代码仍然可以在C ++ 11中编译,但是一旦它尝试从这样一个析构函数中抛出,就会在运行时崩溃。

In C++11, a destructor without any exception specification is implicitly declared with noexcept, which is a change from C++03. Therefore, a code which used to throw from destructors in C++03 would still compile fine in C++11, but will crash at runtime once it attempts throwing from such a destructor.

由于这种代码没有编译时错误,如何将代码库中的所有和所有现有的析构函数声明为$ code> noexcept( false),这将是非常冗长和侵入性的,或检查每一个析构函数的潜在投掷,这将是非常耗时和容易出错,或捕获和修复所有在运行时崩溃,这永远不会保证所有这些情况都被发现?

Since there's no compile-time error with such a code, how could it be safely transitioned to C++11, short of declaring all and every existing destructor in the code base as being noexcept(false), which would be really over-verbose and intrusive, or inspecting each and every destructor for being potentially throwing, which would be really time-consuming and error-prone to do, or catching and fixing all the crashes at runtime, which would never guarantee that all such cases are found?

推荐答案

请注意,规则实际上并不是残酷的。如果一个隐式声明的析构函数将是,析构函数只会隐含地 noexcept 。因此,将至少一个基类或成员类型标记为 noexcept(false)将使整个 noexcept n层次结构/聚合。

Note that the rules are not actually that brutal. The destructor will only be implicitly noexcept if an implicitly declared destructor would be. Therefore, marking at least one base class or member type as noexcept (false) will poison the noexceptness of the whole hierarchy / aggregate.

#include <type_traits>

struct bad_guy
{
  ~bad_guy() noexcept(false) { throw -1; }
};

static_assert(!std::is_nothrow_destructible<bad_guy>::value,
              "It was declared like that");

struct composing
{
  bad_guy member;
};

static_assert(!std::is_nothrow_destructible<composing>::value,
              "The implicity declared d'tor is not noexcept if a member's"
              " d'tor is not");

struct inheriting : bad_guy
{
  ~inheriting() { }
};

static_assert(!std::is_nothrow_destructible<inheriting>::value,
              "The d'tor is not implicitly noexcept if an implicitly"
              " declared d'tor wouldn't be.  An implicitly declared d'tor"
              " is not noexcept if a base d'tor is not.");

struct problematic
{
  ~problematic() { bad_guy {}; }
};

static_assert(std::is_nothrow_destructible<problematic>::value,
              "This is the (only) case you'll have to look for.");

然而,我同意克里斯·贝克,你应该早晚摆脱你抛出的破坏者。他们也可以使您的C ++ 98程序在最不方便的时候爆炸。

Nevertheless, I agree with Chris Beck that you should get rid of your throwing destructors sooner or later. They can also make your C++98 program explode at the most inconvenient times.

这篇关于转换到C ++ 11,其中析构函数被隐含地声明为noexcept的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆