C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Compiler support to use std::apply with template functions

From: Lorand Szollosi <szollosi.lorand_at_[hidden]>
Date: Thu, 23 May 2024 18:48:44 +0200
Hi,

… till the below proposal on overload sets is accepted (also for the case if it’s not accepted), LIFT macro is your friend:

#define LIFT(F) [&](auto&&… args) { return F(std:::forward<decltype(args)>…); }

And then, you can call std::apply(LIFT(Func), std::move(t));

Bests,
-lorro

On 23 May 2024, at 16:25, Brian Bi via Std-Proposals <std-proposals_at_[hidden]> wrote:


Giving `std::apply` the magic ability to accept expressions that no other function can accept would be difficult to implement and confusing for users.

There's a new proposal for compilers to synthesize an "overload-set-type" when a type is deduced from an overload set, which I think would cover this use case: https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3312r0.pdf

On Thu, May 23, 2024 at 10:20 AM Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> wrote:
Let's say we have a template function as follows:

    template<typename... Params>
    auto Func(int const i, double const d, Params&&... args)  // return by value
    {
        return i + d + (std::forward<Params>(args) + ...);
    }

And let's say we have a tuple:

    std::tuple t = { 5, 4.3, 'a', 2.3f };

And now let's say we want to invoke the template function with this tuple:

        std::apply( &Func, std::move(t) );

This will fail to compile because the compiler doesn't know what to do
with "&Func" -- it cannot give you the address of the function unless
you verbosely give it the template parameters as follows:

        std::apply( &Func<char,float>, std::move(t) );

I've been trying to come up with a way of making this possible without
verbosely supplying the template types to the compiler, and the best I
can come up with is as follows:

------ Step 1: Re-write the function as a class's static template method:

    struct FuncClass {
        template<typename... Params>
        static auto Func(int const i, double const d, Params&&...
args)  // return by value
        {
            return i + d + (std::forward<Params>(args) + ...);
        }
    };

------ Step 2: Implement an 'apply_temp' function with the following signature:

    template<class C,typename...Ts>
    decltype(auto) apply_temp(std::tuple<Ts...> &t);

------ Step 3: Invoke 'apply_temp' as follows:

    int main()
    {
        std::tuple t = { 5, 4.3, 'a', 2.3f };

        apply_temp<FuncClass>(t);
    }

I've gotten this working up on GodBolt: https://godbolt.org/z/abTP5Ybsv

But of course the only drawback here is that we need to re-write the
function as a static member function. I wonder would it be possible to
provide a new overload for "std::apply" in C++26 that has compiler
support so that it can be used with template functions? Or perhaps
have a separate function called "std::apply_temp".

Or would it make more sense to propose that C++26 should allow
template functions as template parameters?
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals


--
Brian Bi
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-05-23 16:48:58