I have a class like below:
#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';
}
In the above code, I took advantage of a C 20 concept (std::destructible<T>) to gain some more info about the aforementioned class.
Output:
is nothrow constructible? false
is nothrow destructible? true
I understand the reason why it's not nothrow constructible. E.g. the constructor of std::vector can throw an std::bad_alloc, etc. But why is the destructor nothrow too?
Now if the implicit destructor is nothrow, then would it be better if I marked the destructor noexcept in case I wrote an explicit definition?
CodePudding user response:
Destructors are special. For the implicit destructor as well as user-declared destructors without noexcept specification, the destructor is noexcept(true) by default if all destructors of members and base classes are noexcept(true).
To get a potentially-throwing destructor, you need to explicitly declare it noexcept(false). This is however generally not what one wants, since there will be trouble if the destructor throws while stack unwinding from another exception is in progress.
For ordinary functions, usually the default is noexcept(false), meaning potentially-throwing, if not declared otherwise.
There are a few additional special cases of this kind though, e.g. deallocation functions and (member) functions defaulted on their first declaration.
