C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Automatic perfect forwarding is possible and not too complicated

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Thu, 10 Apr 2025 11:07:32 +0100
On Thu, Apr 10, 2025 at 10:40 AM Rhidian De Wit wrote:
>
> Hi Frederick,
>
> Isn't this a rather small problem to face? Granted an annoying one when it occurs,
> but just not needing to add a single std::forward call in the one appropriate line
> doesn't seem to be worth a language change


I think it would reduce the possibility of introducing
very-hard-to-find bugs. I mean let's say Billy The Programmer started
out by writing the following function:

    template<typename T>
    void ProcessNode(T &&arg)
    {
        NormaliseNode(arg);
        DistributeNode(arg);
        AssimilateNode( forward<T>(arg) );
    }

and the Mandy The Programmer came along a year later and added a new line:

    template<typename T>
    void ProcessNode(T &&arg)
    {
        NormaliseNode(arg);
        DistributeNode(arg);
        AssimilateNode( forward<T>(arg) );
        TrimMemoryUsage( forward<T>(arg) );
    }

Of course this is a very very simple example, and Mandy would be able
to see straight away that 'arg' was already forwarded on the previous
line. But what if the function were 340 lines long, and what if Mandy
missed that 'arg' had previously been forwarded. This bug could lead
to the building of an executable binary that doesn't crash, but
behaves oddly only for a few corner cases. The person tasked with
fixing this bug might spend a long time trying to figure out what's
gone wrong.

The whole point of the trigraph reference is that it means that the
programmer can no longer make the mistake.



> and one that makes references harder to read, making it more confusing for beginners as well,
> as we'd have &, && and &&& which doesn't really follow the rules of the previous 2.


I'm not too fussed about the syntax, i.e. whether it's a symbol or a
word or whatever. It could as easily be written as:

    template<typename T>
    void ProcessNode(T &&arg [[auto_forward]])

Just now I asked ChatGPT to give me 20 possible ways of writing it:

    template<typename T> void ProcessNode( T &&&arg )
    template<typename T> void ProcessNode( T&|&arg )
    template<typename T> void ProcessNode( T&!&arg )
    template<typename T> void ProcessNode( T&^&arg )
    template<typename T> void ProcessNode( forwardref<T> arg )
    template<typename T> void ProcessNode( autoforward<T&&> arg )
    template<typename T> void ProcessNode( T&& autoforward arg )
    template<typename T> void ProcessNode( forward T&& arg )
    template<typename T> void ProcessNode( T&& arg forward )
    template<typename T> void ProcessNode( T&& arg [[autoforward]] )
    template<typename T> void ProcessNode( T&& arg [[forwarding_ref]] )
    template<typename T> void ProcessNode( T&& arg [[pass_through]] )
    template<typename T> void ProcessNode( T&& arg [[binds_to_any]] )
    template<typename T> void ProcessNode( T&& arg [[perfect]] )
    template<typename T> void ProcessNode( forward<T> arg )
    template<typename T> void ProcessNode( auto&& arg = forward<T> )
    template<typename T> void ProcessNode( T&& arg = auto_forward )
    template<typename T> void ProcessNode( forwardref auto arg )
    template<typename T> void ProcessNode( T>>> arg )
    template<typename T> void ProcessNode( T&&... arg ) // reimagined
ellipsis use

Received on 2025-04-10 10:07:45