Date: Thu, 23 May 2024 10:24:20 -0400
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
>
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*
Received on 2024-05-23 14:25:04