I am trying to construct a function tune
that takes a templated function via std::function
and initializes a series of that function based on a std::integer_sequence
. I am not sure whether this is possible, and I am stuck. I made a working example that shows what I aim to achieve: a generic function that takes another function and an integer list as an argument. I would like to be able to use the syntax that is in the two lines commented out in the bottom, because with the working code, I have to make a tune
function for each function.
#include <iostream>
#include <functional>
template<int I> void print_value() { std::cout << I << std::endl; }
template<int I> void print_value_squared() { std::cout << I*I << std::endl; }
template<int... Is>
void tune_print_value(std::integer_sequence<int, Is...>)
{
(print_value<Is>(), ...);
}
/* NOT SURE HOW TO DO THIS...
template<class Func&&, int... Is>
void tune(std::function<Func> f, std::integer_sequence<int, Is...)
{
(f<Is>(), ...);
}
*/
int main()
{
std::integer_sequence<int, 1, 2, 3> is;
tune_print_value(is);
// I would like:
// tune(print_value, is);
// tune(print_value_squared, is);
return 0;
}
This is not possible with a simple function pointer or std::function
(as it can only point to one instance of a particular template!) but what you can do though is to wrap each function print_value
or print_value_squared
in a corresponding struct
struct print_value {
template <int I>
static constexpr int impl() {
std::cout << I << std::endl;
return I;
}
};
This struct then holds the templated implementation as a static
member function with a predefined name such as impl
(sadly you can't use operator ()
like for a functor as it is not allowed to be static
)
Your tune function then takes this struct
as a template argument and "magically" (in C++20 you could create a concept for this as follows , prior to it you might use SFINAE and std::enable_if
as follows ) accesses the wrapped template function impl
.
template<class Func, int... Is>
auto tune(std::integer_sequence<int, Is...>) {
return (Func::template impl<Is>(), ...);
}
You will need the keyword template
as a qualifier in this case to tell the compiler that the member function is a template.
You can then call the tune
function like
tune<print_value>(is);
Try it here with a static member function impl
or here with a non-static operator()
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.