Date: Sat, 25 Jun 2022 17:44:22 -0400
Hi std-proposals:
As the original paper author of P1132, I support such a change. I had
it in my original proposal (and my original implementation) but it was
removed in the very first iterations as "not really necessary". I had a few
use cases but they were minimal and I was code-owner, so I could simply
work around such an operator's non-existence.
As a knee-jerk (instantaneous, intrinsic) reaction to Andrew Giese's
suggestion, I originally thought "can't you just do
*std::out_ptr(smart_ptr) and get the same effect?", but such an operation
is ambiguous between the `void**` and `Pointer*` conversion operators in
the general case. (Does not apply if Pointer* is void** and therefore the
member does not exist in the specification).
I support such a change. (I will not write a paper for it; I am tired.
You can quote this e-mail as support from the original author and put it
into any such paper, if it aids you expedite the proposal writing process.)
Sincerely,
JeanHeyd
On Sat, Jun 25, 2022 at 4:57 PM Andrew Giese via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> 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.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
As the original paper author of P1132, I support such a change. I had
it in my original proposal (and my original implementation) but it was
removed in the very first iterations as "not really necessary". I had a few
use cases but they were minimal and I was code-owner, so I could simply
work around such an operator's non-existence.
As a knee-jerk (instantaneous, intrinsic) reaction to Andrew Giese's
suggestion, I originally thought "can't you just do
*std::out_ptr(smart_ptr) and get the same effect?", but such an operation
is ambiguous between the `void**` and `Pointer*` conversion operators in
the general case. (Does not apply if Pointer* is void** and therefore the
member does not exist in the specification).
I support such a change. (I will not write a paper for it; I am tired.
You can quote this e-mail as support from the original author and put it
into any such paper, if it aids you expedite the proposal writing process.)
Sincerely,
JeanHeyd
On Sat, Jun 25, 2022 at 4:57 PM Andrew Giese via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> 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.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2022-06-25 21:44:36