class 不可抛出构造但不可抛出破坏

class is not nothrow constructible but is nothrow destructible

我有一个 class 如下所示:

#include <iostream>
#include <type_traits>
#include <concepts>
#include <vector>

class Foo
{
public:
    Foo( )
    : m_member1( 1 ), m_member2( 2 ), m_member3( std::vector<char>( 1 * 2, '-' ) )
    {
    }

    // ~Foo( ) is not defined (i.e. implicitly declared by the compiler)

private:
    int m_member1;
    int m_member2;
    std::vector<char> m_member3;
};

int main( )
{
    std::cout << std::boolalpha << "is nothrow constructible? " << std::is_nothrow_constructible_v<Foo> << '\n'
                                << "is nothrow destructible? " << std::destructible<Foo> << '\n';
}

在上面的代码中,我利用了 C++20 概念 (std::destructible<T>) 来获取有关上述 class.

的更多信息

输出:

is nothrow constructible? false
is nothrow destructible? true

我明白为什么它不可构造。例如。 std::vector 的构造函数可以抛出 std::bad_alloc,等等。但是为什么析构函数 也不会抛出
现在,如果隐式析构函数是 nothrow,那么如果我将析构函数标记为 noexcept 以防我写一个显式定义,会不会更好?

析构函数很特别。对于隐式析构函数以及没有 noexcept 规范的用户声明的析构函数,如果成员和基 类 的所有析构函数都是 noexcept(true).[=,则析构函数默认为 noexcept(true) 15=]

要获得潜在抛出的析构函数,您需要显式声明它noexcept(false)。然而,这通常不是人们想要的,因为如果在从另一个异常中展开堆栈时析构函数抛出,将会出现问题。

对于普通函数,通常默认为noexcept(false),意思是潜在抛出,如果没有另外声明的话。

不过,还有一些此类特殊情况,例如解除分配函数和(成员)函数在第一次声明时默认。