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.
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