There's an easier way to spell "&&o&&": "o".

Compilers can certainly tell when the result of std::move is passed to a move constructor to initialize a function parameter; warning on subsequent use is definitely feasible (though not always desired). 

On Fri, Jun 23, 2023, 08:34 Frederick Virchanza Gotham via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Thu, Jun 22, 2023 at 6:17 PM Hyman Rosen via Std-Proposals
<std-proposals@lists.isocpp.org> wrote:
>
> It may also be reasonable for someone to do
>
> void F(C &&o) {
>     A_MightTake(move(o));
>     B_MightTake(move(o));
>     ...
> }
>
> to let a sequence of functions examine an object
> and maybe take it, maybe not.  First one that
> wants it, gets it, the rest see a moved-from
> empty object.


Okay then how about my proposed compiler warning/error only kicks in
when then Rvalue reference is marked with postfix '&&'   ?

So the following would fail to compile:

    void F(C &&o&&)
    {
        A_MightTake( o );
        B_MightTake( o );  // possible double-move
    }

And in order to alleviate this error, you would abandon the use of the
postfix '&&' operator, and you would simply mark the function
parameter as "&&o" instead of "&&o&&", and use 'std::move' as normal.

By the way, when it comes to marking a function parameter with both
prefix and postfix '&&', it would have no effect in a function
declaration, i.e. the following two function signatures are
equivalent:

    void F(C &&o);
    void F(C &&o&&);

There would be a difference however in the function definition as follows:

    void F(C &&o&&)
    {
        // In here, 'o' is always an R-value (no need for 'move' or 'forward')
    }

So if you decide to change a function parameter from "&&o" to "&&o&&",
then none of the header files need to change.
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals