How should I make sure that a constructor is noexcept
if the allocator does not throw?
Here is an MRE:
#include <iostream>
#include <array>
#include <vector>
#include <memory_resource>
#include <concepts>
#include <cstddef>
template < std::unsigned_integral T, class Allocator = std::allocator<T> >
class Foo
{
std::vector<T, Allocator> vec;
public:
Foo( const size_t size, const T value,
const Allocator& alloc = Allocator { } ) noexcept( noexcept( Allocator { } ) )
: vec { size, value, alloc }
{
}
};
int main( )
{
Foo<unsigned> my_foo { 10, 505 };
auto buffer { std::array<std::byte, 50> { } };
std::pmr::monotonic_buffer_resource rsrc { buffer.data( ), buffer.size( ) };
Foo< unsigned, std::pmr::polymorphic_allocator<unsigned> > my_foo_pmr { 10, 505, &rsrc };
std::cout << std::boolalpha
<< noexcept( std::pmr::polymorphic_allocator<unsigned> { } ) << '\n' // true
<< noexcept( std::allocator<unsigned> { } ) << '\n' // true
<< std::noboolalpha;
}
First of all, I wonder why does noexcept( std::allocator<unsigned> { } )
return true? Is std::allocator<unsigned>
exception safe? Like a vector with this allocator never throws? And what about the pmr allocator that has a stack-based buffer? Can it throw?
Secondly, what is the proper way of ensuring that the above class's ctor is marked noexcept
if it actually never throws?
CodePudding user response:
First of all, I wonder why does
noexcept( std::allocator<unsigned> { } )
returntrue
?
Because constructing a std::allocator<unsigned>
does not throw.
Secondly, what is the proper way of ensuring that the above class's ctor is marked noexcept if it actually never throws?
The proper way is to not mark it as noexcept
because it may throw. The vector constructor you are calling is not noexcept
. Only std::vectors
default constructor is noexcept( noexcept(Allocator())
, but you are calling a different constructor. With a pmr
allocator I suppose nothing is different, because when size
is too big then being able to construct the allocator without exceptions does not help to avoid running out of memory once you allocate too many elements.