【问题标题】:How to specify nothrow exception specifier for destructor?如何为析构函数指定 nothrow 异常说明符?
【发布时间】:2015-02-19 01:46:31
【问题描述】:

每当Foo 的析构函数没有抛出时,我试图指定一个函数是nothrow。我可以通过使用类型特征std::is_nothrow_destructible<> 来做到这一点。我怎样才能直接做到这一点?我已经尝试了以下方法,但如果我取消注释注释行,它不会编译

#include <iostream>
#include <type_traits>

class Foo
{
public:
    ~Foo() noexcept {}
};

// void f() noexcept(noexcept(~Foo{})) { } // error here
void g() noexcept(std::is_nothrow_destructible<Foo>::value) 
{

}

int main()
{
    g();
}

我收到一个错误

 error: no match for 'operator~' (operand type is 'Foo')

错误说明符noexcept(noexcept(~Foo())) 不行,尽管对于构造函数我可以使用noexcept(noexcept(Foo()))。我在这里遗漏了一些明显的语法吗?

【问题讨论】:

  • 析构函数永远不应该抛出异常。
  • 析构函数隐式为noexcept(true),因此无需仅为noexcept 规范添加用户定义的析构函数。
  • @PaulMcKenzie 是的,我知道这一点,我只是在搞砸nothrow 并遇到了这个问题。

标签: c++ exception c++11 nothrow


【解决方案1】:

只能通过成员访问表达式调用析构函数。所以语法是:

void f() noexcept(noexcept(std::declval<Foo>().~Foo()))

【讨论】:

  • 不对称是因为对于noexcept(expr)expr 必须是一个有效的表达式。 Foo() 是可能出现在 noexcept 说明符之外的有效表达式,但 ~Foo() 不是。但是,您可以写 Foo f; f.~Foo(),这实际上就是这个答案的作用。
  • @TavianBarnes declval 不会创建任何临时变量,它使用未计算的表达式。
  • @0x499602D2 更大的问题是“~Foo() 应该破坏什么?”
  • @vsoftco 构造函数创建一个新实例,必须在现有实例上调用析构函数。 declval 表达式提供了这个实例(实际上没有创建一个)。
  • @0x499602D2: 我不认为这是 ambiguous...~Foo() 明确否定了默认构造的Foo,因为只有在存在时才会考虑析构函数成员函数调用语法ala a_foo.~Foo().
猜你喜欢
  • 2016-01-08
  • 1970-01-01
  • 2011-06-02
  • 1970-01-01
  • 2016-06-09
  • 2019-10-29
  • 2013-03-14
  • 2014-07-06
  • 2015-08-26
相关资源
最近更新 更多