std::unique_ptr with a deleter that throws an exception

The program below is terminated when the deleter throws the exception:

#include <iostream>
#include <memory>

struct X
{
    int value;
};

struct Deleter
{
    void operator()(X* p) noexcept(false)
    {
        if (p->value == 0)
        {
            throw std::logic_error("Can't delete a zero.");
        }

        delete p;
    }
};
int main()
{
    try
    {
        std::unique_ptr<X, Deleter> p(new X{});

        p.reset();

        std::cout << "reset" << std::endl;
    }
    catch (const std::exception& e)
    {
        std::cout << e.what();
    }

    return 0;
}

It is because reset() method is declared with noexcept (MSVC version):

void reset(pointer _Ptr = nullptr) noexcept {
    pointer _Old = _STD exchange(_Mypair._Myval2, _Ptr);
    if (_Old) {
        _Mypair._Get_first()(_Old);
    }
}

Leave a Reply

Your email address will not be published.