C++ Logo

std-proposals

Advanced search

[std-proposals] Achieving NRVO with std::factory and std::after_factory

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Sat, 8 Jun 2024 21:29:43 +0100
On Mon, May 20, 2024 at 9:51 PM Sebastian Wittmeier wrote:
>
> This feature request could be also made to a standard library function.
>
> // Calls the constructor and a setup function. With guaranteed RVO.
>
> T std::factory<T>(params, ..., setup)
>
> No need for other language changes or any special exception handling.


I'm renaming this fork of the thread to "std::factory" because it has
nothing to do with "std::elide".

Since the main paper on NRVO written by Anton might not make it into
C++26 -- it's looking like it won't -- I think we should talk about
having something to temporarily (or permanently) fill the gap until
then.

The first function to discuss is "std::factory", it modifies an object
after constructing it, and returns a PRvalue. It can be used as
follows:

    mutex m = std::factory<mutex>( [](auto &a){ a.lock(); } );

The second function to discuss is "std::after_factory" which can be
used to modify a PRvalue.

So to begin with, let's say we have a function called 'Func' that
returns a locked mutex:

    mutex Func(void)
    {
        return std::factory<mutex>( [](auto &a){ a.lock(); } );
    }

And now let's say we want to invoke 'Func' to get a locked mutex, and
then we want to unlock the mutex, and then we want to return the
locked-and-then-unlocked mutex by value, as follows:

    mutex Func(void)
    {
        return std::factory<mutex>( [](auto &a){ a.lock(); } );
    }

    mutex Func2(void)
    {
        return std::after_factory( Func, [](auto &a){ a.unlock(); } );
    }

Both 'std::factory' and 'std::after_factory' can be supplied with
arguments to pass to the constructor (or to the callable functor). For
example:

    binary_semaphore Func(void)
    {
        return std::factory<binary_semaphore>( 1, [](auto &a){ a.lock(); } );
    }

    binary_semaphore Func2(void)
    {
        return std::after_factory( Func, 1, [](auto &a){ a.unlock(); } );
    }

What do you reckon, should we finalise a paper on these two functions
to get them into C++26? And then some time in the future maybe Anton's
NRVO paper will make it in.

Received on 2024-06-08 20:29:54