#include <iostream>
template <typename... Ts> void Print(Ts... args) {
(std::cout << ... << args) << std::endl;
}
template <typename T> void Add(T a, T b) { Print(a + b); }
template <typename T> void Sub(T a, T b) { Print(a - b); }
template <typename T> void Mul(T a, T b) { Print(a * b); }
template <typename F, typename... Fns> void CallFuncs(F a, F b, Fns... fns) {
(fns(a, b), ...);
};
void FunctionInvokeTest() { CallFuncs(1, 2, Add<int>, Mul<int>); }
int main() {
FunctionInvokeTest();
return 0;
}
I want to pass the template function as parameter shown as above. The code works. However I must put <int>
after the function such as Add<int>
.
If this is non-deductible context, then is there another way to allow me write like this, where the Add
and Mul
are still template functions?
CallFuncs(1,2, Add, Mul);
You can't do it directly, but you can turn functions into function objects:
struct Add {
template<typename T>
void operator()(T a, T b) {
Print(a + b); }
};
struct Mul {
template<typename T>
void operator()(T a, T b) {
Print(a * b); }
};
template<typename F, typename... Fns>
void CallFuncs(F a, F b, Fns... fns) {
(fns(a, b), ...);
};
void FunctionInvokeTest() {
CallFuncs(1, 2, Add{}, Mul{});
}
T
will be deduced from the type of a
and b
. In this example it will be int
. To get double
, you need double
parameters:
CallFuncs(1., 2., Add{}, Mul{});
or explicit type specification:
CallFuncs<double>(1, 2, Add{}, Mul{});
This is very similar to "diamond" functors in the standard library (since C++14). For example, the std::plus
declaration is
template<class T = void>
struct plus;
If T
is void
(e.g., in std::plus<>{}
), plus::operator()
deduces argument and return types. Typical implementation looks like this (with some minor simplifications):
template<> struct plus<void> {
template<typename Tp, typename Up>
constexpr auto operator()(Tp&& t, Up&& u) const {
return std::forward<Tp>(t) + std::forward<Up>(u);
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With