Is it possible to have a generic method which takes in two functions f
and g
(both returning void
and taking in arguments of the same type) and return a new function which takes in arguments of the same type as f
and g
and first applies f
to the passed arguments and then g
?
Specifically, I want to define something like this:
template <typename FunctionType>
// FunctionType is void(ArgType1 arg1, ArgType2 arg2, ..)
FunctionType CombineTwoFunctions(FunctionType f, FunctionType g) {
// Using the lambda syntax just for illustration:
return [f, g](ArgsOf(FunctionType) args) {
f(args);
g(args);
};
}
Not the most optimised code, but it works.
With help of make_function
from this answer
template <typename ...Args>
std::function<void(Args...)> CombineTwoFunctionsHelper(std::function<void(Args...)> f, std::function<void(Args...)> g) {
return [f, g](Args ...args) {
f(args...);
g(args...);
};
}
template <typename F1, typename F2>
auto CombineTwoFunctions(F1 f1, F2 f2) -> decltype(make_function(f1)) {
return CombineTwoFunctionsHelper(make_function(f1), make_function(f2));
}
void print1(int i, std::string s) {
std::cout << "print1 " << i << s << std::endl;
}
void print2(int i, std::string s) {
std::cout << "print2 " << i << s << std::endl;
}
int main() {
auto fg = CombineTwoFunctions(print1, print2);
fg(1, "test");
}
You should be able to improve it by adding (universal) references to argument and forward them to avoid copies. But note that you cannot move an argument twice.
As @0x499602D2 said in the comment, C++14 make it much eaiser
template <typename F1, typename F2>
auto CombineTwoFunctions(F1 f, F2 g) {
return [f, g](auto&& ...args) {
f(args...);
g(args...);
};
}
void print1(int i, std::string s) {
std::cout << "print1 " << i << s << std::endl;
}
void print2(int i, std::string s) {
std::cout << "print2 " << i << s << std::endl;
}
int main() {
auto fg = CombineTwoFunctions(print1, print2);
fg(1, "test");
}
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.