C++ Logo

std-proposals

Advanced search

[std-proposals] P1132: out_ptr should include an overload for Pointer*&

From: Andrew Giese <gieseanw_at_[hidden]>
Date: Sat, 25 Jun 2022 15:57:25 -0500
Currently the proposal for std::out_ptr outlined in P1132R8 (
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1132r8.html#wording-library)
gives std::out_ptr only implicit conversion operators to its pointer type
or void**:

template <class Smart, class Pointer, class... Args>
 class out_ptr_t {
 public:
  // 20.11.9.1, constructors
  explicit out_ptr_t(Smart&, Args...);
  out_ptr_t(const out_ptr_t&) = delete;

  // 20.11.9.2, destructors
  ~out_ptr_t();

  // 20.11.9.3, conversion operators
  operator Pointer*() const noexcept;
  operator void**() const noexcept;

 private:
  Smart& s; // exposition only
  tuple<Args...> a; // exposition only
  Pointer p; // exposition only
 };





I could see plenty of utility in adding an additional operator Pointer*&
that would support legacy C++ api's (e.g., factory methods) that assigned
to output pointers by lvalue reference.

Here's a contrived example (godbolt link: https://godbolt.org/z/G9GofMbxd)


#include <iostream>
#include <memory>

struct FakeOutPtr
{
    FakeOutPtr(std::unique_ptr<int>& ptr)
    : m_smart_ptr(std::addressof(ptr))
    {}
    ~FakeOutPtr()
    {
        m_smart_ptr->reset(storage);
    }
    std::unique_ptr<int>* m_smart_ptr;
    int* storage = nullptr;
    operator int*(){return storage;}
    operator void**(){return
static_cast<void**>(static_cast<void*>(storage));}
    operator int*&(){return storage;}
};

void assign(int*& ptr)
{
  ptr = new int(42);
}


int main()
{
    std::unique_ptr<int> my_ptr;
    assign(FakeOutPtr(my_ptr));
    std::cout << *my_ptr;
}

The above could would not compile with the current proposal. I think the
addition of an implicit conversion to Pointer*& provides a lot of utility
in exchange for not a lot more complexity to the proposal.

Received on 2022-06-25 20:57:29