Date: Thu, 23 May 2024 15:20:02 +0100
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?
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?
Received on 2024-05-23 14:20:15