标签: exception-specification

关于Hinnant的堆栈分配器的问题

我一直在使用Howard Hinnant的堆栈分配器,它就像一个魅力,但实现的一些细节对我来说有点不清楚.

  1. 为什么全球运营商newdelete使用?的allocate()deallocate()成员函数使用::operator new::operator delete分别.同样,成员函数construct()使用全局布局new.为什么不允许任何用户定义的全局或类特定的重载?
  2. 为什么对齐设置为硬编码16字节而不是std::alignment_of<T>
  3. 为什么构造函数和max_sizethrow()异常规范?这不是劝阻(参见例如更有效的C++第14项)?在分配器中发生异常时,是否真的有必要终止和中止?这是否随新的C++ 11 noexcept关键字而改变?
  4. construct()成员函数将是完美转发(在构造函数被调用)的理想选择.这是编写符合C++ 11标准的分配器的方法吗?
  5. 还需要进行哪些其他更改才能使当前代码C++ 11符合要求?

c++ memory-alignment exception-specification allocator c++11

32
推荐指数
1
解决办法
3149
查看次数

std :: runtime_error :: runtime_error(const std :: string&)如何满足std :: exception对throw()的要求?

std::exception要求它的构造函数是throw().然而std::runtime_error接受一个std::string作为它的论据,这表明它存储在std::string某个地方.因此,必须在某处进行分配或复制构造.而且std::string,这不是一项nothrow行动.

怎么会runtime_error::runtime_error遇到throw()

(对于上下文,我正在实现一个异常类型,并希望std::string从调用站点存储几个,我想要正确地执行它...)

c++ exception-specification

17
推荐指数
2
解决办法
3790
查看次数

例外规范

我知道这个功能将在C++ 0x中弃用,但对我来说,作为一个新手,拥有它似乎是一个好主意.任何人都可以向我解释为什么不是一个好主意?

c++ exception exception-specification

14
推荐指数
1
解决办法
649
查看次数

异常规范如何影响虚拟析构函数覆盖?

C++标准声明了以下关于具有异常规范的虚函数:

如果虚函数具有异常规范,则任何在任何派生类中覆盖该虚函数的函数的所有声明(包括定义)都只允许基类虚函数的异常规范所允许的异常(C +) +03§15.4/ 3).

因此,以下是不正确的:

struct B {
    virtual void f() throw() { } // allows no exceptions
};
struct D : B {
    virtual void f() { }         // allows all exceptions
};
Run Code Online (Sandbox Code Playgroud)

(1)此规则是否适用于析构函数?也就是说,以下是否良好?

struct B {
    virtual ~B() throw() { }
};
struct D : B {
    virtual ~D() { }
};
Run Code Online (Sandbox Code Playgroud)

(2)此规则如何应用于隐式声明的析构函数?也就是说,以下是否良好?

struct B {
    virtual ~B() throw() { }
};
struct D : B { 
    // ~D() implicitly declared …
Run Code Online (Sandbox Code Playgroud)

c++ destructor exception-handling exception exception-specification

13
推荐指数
1
解决办法
5139
查看次数

c ++ 1z动态异常规范错误

我正在尝试使用新的GCC版本7.2.1编译我的项目,并且遇到动态异常规范的问题:

error: ISO C++1z does not allow dynamic exception specifications
  MEMORY_ALLOC_OPERATORS(SQLException)
Run Code Online (Sandbox Code Playgroud)

问题是这些错误来自我无法控制的第三方库.

有没有办法解决它?据我所知,我不能告诉编译器用警告替换错误.使用--std=c++14不是一个选项,因为我想使用C++ 1z的新功能.

c++ exception-specification c++17 gcc7

13
推荐指数
2
解决办法
5599
查看次数

转换到C++ 11,其中使用noexcept隐式声明析构函数

在C++ 11中,隐式声明了没有任何异常规范的析构函数 noexcept,这是对C++ 03的更改.因此,用于从C++ 03中的析构函数抛出的代码仍然可以在C++ 11中正常编译,但是一旦尝试从这样的析构函数抛出就会在运行时崩溃.

由于这样的代码没有编译时错误,如何将它安全地转换为C++ 11,而不是将代码库中的所有现有析构函数声明为noexcept(false),这实际上是过于冗长和干扰,或者检查每个析构函数是否有可能抛出,这将非常耗时且容易出错,或者在运行时捕获并修复所有崩溃,这永远无法保证找到所有这些情况?

c++ destructor exception-handling exception-specification c++11

11
推荐指数
3
解决办法
1919
查看次数

有一个普遍接受的习惯用于指示C++代码可以抛出异常吗?

我在使用C++代码时遇到了问题,这些代码意外地对调用者抛出异常.读取用于查看是否抛出异常的模块的每一行并不总是可行或实际的,如果是,则抛出异常类型.

是否存在处理此问题的成语或"最佳实践"?

我想到了以下几点:

  1. 在我们的doxygen文档中,我们可以在每个预期会抛出异常及其类型的函数中添加注释.

    • 加号:简单.
    • 缺点:受用户错误的影响.
  2. 我们可以安装应用程序try/catch(...).

    • 优点:我们不会再有任何未被捕获的例外情况了.
    • 缺点:异常远离投掷.很难弄清楚做什么或出了什么问题.
  3. 使用例外规范

    • 优点:这是处理这个问题的语言认可方式.
    • 缺点:重构问题库以使其有效.在编译时没有强制执行,因此违规会变成运行时问题,这正是我想要避免的!

有这些方法的经验,还是我不知道的任何其他方法?

c++ exception exception-specification

10
推荐指数
3
解决办法
1425
查看次数

将删除的函数声明为noexcept是否有任何意义?

考虑这两个可能的类定义:

图表A:

struct A
{
    A() = delete;
};
Run Code Online (Sandbox Code Playgroud)

图表A':

struct A
{
    A() noexcept = delete;
}
Run Code Online (Sandbox Code Playgroud)

声明删除的函数是否有任何意义noexcept

c++ exception-specification deleted-functions noexcept

10
推荐指数
1
解决办法
275
查看次数

从C++ 11中的std :: exception派生时的异常规范

我有一个异常类如下:

#include <exception>

struct InvalidPathException : public std::exception
{
   explicit InvalidPathException() {}
   const char* what() const;
};

const char*
InvalidPathException::what() const {
    return "Path is not valid";
}
Run Code Online (Sandbox Code Playgroud)

使用-Wall -std = c ++ 0x在GCC 4.4下编译时

错误:对'virtual const char*的错误抛出说明符*InvalidPathException :: what()const'

错误:覆盖'virtual const char*std :: exception :: what()const throw()'

完全正确,也因为我重写std::exceptionwhat()是确实有一个方法throw()异常说明.但是,通常会通知我们,我们不应该使用异常说明符.据我所知,它们在C++ 11弃用,但显然还没有在GCC中使用-std = c ++ 0x.

所以我现在对最好的方法感兴趣.在我正在开发的代码中,我确实关心性能,所以担心经常提到的开销throw(),但实际上这个开销是如此严重?我是否正确地认为我只会在what()实际调用时遇到它,这只会在抛出这样的异常之后(同样对于从std :: exception继承的其他方法都有throw()说明符)?

或者,有没有办法解决GCC给出的这个错误?

c++ gcc exception-specification c++11

9
推荐指数
1
解决办法
5393
查看次数

C++ 11中默认虚拟析构函数的异常规范是什么?

假设我有:

class Foo
{
public:
   virtual ~Foo()=default;
};
Run Code Online (Sandbox Code Playgroud)

默认析构函数的异常规范是什么?违约的析构函数是否相当于:

   virtual ~Foo() {};
or
   virtual ~Foo() throw() {};
or
   virtual ~Foo() noexcept {};
Run Code Online (Sandbox Code Playgroud)

C++ 11标准的第15.4节说它依赖于析构函数的隐式定义直接调用的函数的异常规范.在这种情况下,没有成员,也没有基类,因此AFAIK没有隐式析构函数直接调用的函数.这是标准中的含糊不清(或遗漏)吗?

当然,这很重要,因为如果它隐式具有throw(),那么所有子类必须使用throw()声明它们的析构函数.不要告诉我在析构函数中抛出异常是个坏主意,我知道.我处理了许多遗留代码,其中根本没有使用异常规范.

作为一个信息点,当我尝试时:

class SubFoo : public Foo
{
public:
   virtual ~SubFoo();
};
Run Code Online (Sandbox Code Playgroud)

我在GCC 4.4中得到了一个错误(不匹配的异常规范)(尽管我承认我可能没有正确的命令行开关),但在使用"11"编译器的XCode 4.3中却没有.

c++ default exception-specification

9
推荐指数
1
解决办法
2857
查看次数