2

Here's what I have:

Demo

#include <cstdio>
#include <memory_resource>
#include <memory>
#include <string_view>
#include <array>
#include <utility> /* declval */


struct msg_outbound_t
{
    std::string_view hello_ = "Hello World!";
};

// Default deleter - works

// using msg_handle_t = std::unique_ptr<msg_outbound_t>;

// Custom deleter - doesn't work

using allocator_t = std::pmr::polymorphic_allocator<std::byte>;

auto pmr_deleter(allocator_t allocator) {
    return [allocator](msg_outbound_t* p) mutable { allocator.delete_object(p); };
}

using msg_handle_t = std::unique_ptr<msg_outbound_t, decltype(pmr_deleter(std::declval<allocator_t>()))>;


int main()
{
    std::array<msg_handle_t, 8> myarray;
}

It doesn't work as it seems that unique_ptrs with custom deleters can't be default constructed? Is there a workaround to create an array of them?

Errors:

<source>:31:33: error: use of deleted function 'std::array<std::unique_ptr<msg_outbound_t, pmr_deleter(allocator_t)::<lambda(msg_outbound_t*)> >, 8>::array()'
   31 |     std::array<msg_handle_t, 8> myarray;
      |                                 ^~~~~~~
glades
  • 3,778
  • 1
  • 12
  • 34

1 Answers1

2

it seems that unique_ptrs with custom deleters can't be default constructed?

Yes, but you'll have to supply a class that it can instantiate as a template parameter:

using allocator_t = std::pmr::polymorphic_allocator<std::byte>;

struct pmr_deleter {
    void operator()(msg_outbound_t * p) {
         allocator.delete_object(p);
    }
    allocator_t allocator;
};

using msg_handle_t = std::unique_ptr<msg_outbound_t, pmr_deleter>;

Demo

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • Well I was thinking I was doing that by providing a lambda? But now you have left out the closure of the allocator. I get both is not possible? I mean a default constructed unique_ptr wouldn't even have to delete anything so I don't understand why it is deleted in the first place. – glades Dec 31 '22 at 15:08
  • @glades Your `pmr_deleter` lambda requires `allocator` to be captured but there is no `allocator_t` instance in your code. What do you mean by _"now you have left out the closure of the allocator"_? A default constructed `unique_ptr` doesn't call the deleter. – Ted Lyngmo Dec 31 '22 at 15:17
  • @glades Do you have any follow-up question or did my answer clear it up? – Ted Lyngmo Jan 07 '23 at 01:47
  • 1
    Thanks no your answer was very clear. I'm using such an implementation right now, – glades Jan 07 '23 at 10:22
  • 1
    Sorry missed that! Accepted now! – glades Jan 07 '23 at 10:43