Proposal: allow std::out_ptr and std::inout_ptr

21 views
Skip to first unread message

Victor Vianna

unread,
Jan 26, 2026, 4:48:07 PM (5 days ago) Jan 26
to cxx
Here is a snippet with an example use.

```

struct Foo {};


// Legacy C-like API for creating an object Foo.

bool TryCreateFoo(Foo** out);


void BeforeCpp23() {

  Foo* foo_raw = nullptr;

  if (!TryCreateFoo(&foo_raw)) {

    return;

  }

  std::unique_ptr<Foo> foo(foo_raw);

  // …

}


void AfterCpp23() {

  std::unique_ptr<Foo> foo;

  // Sets `foo` directly without requiring an extra var.

  if (!TryCreateFoo(std::out_ptr(foo))) {

    return;

  }

  // …

}

```

And if TryCreateFoo() can read `out`, std::inout_ptr should be used instead.

David Baron

unread,
Jan 26, 2026, 8:20:58 PM (5 days ago) Jan 26
to Victor Vianna, cxx
I'm generally supportive of allowing these.

I spent a long time working on a large codebase (Gecko) that had helpers like these for a number of its smart pointer classes.  They were generally useful.

It looks like std::out_ptr is better in one way than the one that Gecko had in that (if I'm understanding cppreference's explanation of std::out_ptr_t correctly) it assigns the new value to the smart pointer using effectively a regular assignment (dropping the old value at the same time) when the temporary std::out_ptr_t is destroyed.  (This is different from Gecko's equivalent which released the old value of the smart pointer when the temporary was constructed and then provided a pointer to the smart pointer class's internal storage; this occasionally led to very interesting bugs when used on smart pointer *member* variables that were mutated between the two operations by a different function.)

That said, this behavior difference relative to the Gecko behavior makes one other case potentially problematic.  I wonder if it's worth having any guidelines or checks related to the use of std::out_ptr in complex statements.  Given the timing of temporary destruction (assuming I'm remembering it correctly), it can produce unexpected results if the smart pointer is referenced within the same statement.  For example, if I'm understanding std::out_ptr correctly, the following statement:

  if (!TryCreateFoo(std::out_ptr(foo)) || !foo) {

    return;

  }


would not behave as the author expected, and I'm wondering if it's worth any kind of guidance or checks for this case.


-David

--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CANFyMwzEJYSOqgSqPWAxFP12_W68XV0h42x%2BB4P%2BbUZHrp4rWw%40mail.gmail.com.

Joe Mason

unread,
Jan 27, 2026, 12:11:31 PM (4 days ago) Jan 27
to David Baron, Victor Vianna, cxx
It's also worth deciding whether we should allow people to define specializations of std::out_ptr_t, to support new smart pointer types. 


It is not recommended to create an out_ptr_t object of a storage duration other than automatic storage duration, because such code is likely to produce dangling references and result in undefined behavior on destruction.

Ban this explicitly? 




Reply all
Reply to author
Forward
0 new messages