#include <iostream>
//A functor to store the input functions and call them
template <typename LEFT, typename RIGHT>
struct combine_functions {
private:
LEFT left;
RIGHT right;
public:
combine_functions(const LEFT &left, const RIGHT &right)
: left(left), right(right) {}
template <typename ...ARGS>
auto operator()(ARGS&... args) const
-> decltype(left(args...), static_cast<void>(right(args...)))
{
left(args...);
right(args...);
}
};
//I should probably have an enable if that checks the arguments
//are function pointers or functors
template <typename LEFT, typename RIGHT>
combine_functions<
std::decay_t<LEFT>,
std::decay_t<RIGHT>
>
concat(
const LEFT &left,
const RIGHT &right
) {
return {left, right};
}
int main()
{
concat([](const auto& t) {std::cout << t;},
[](const auto& t) {std::cerr << t;})
("Hello world");
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKLy9BIGZ1bmN0b3IgdG8gc3RvcmUgdGhlIGlucHV0IGZ1bmN0aW9ucyBhbmQgY2FsbCB0aGVtCnRlbXBsYXRlIDx0eXBlbmFtZSBMRUZULCB0eXBlbmFtZSBSSUdIVD4Kc3RydWN0IGNvbWJpbmVfZnVuY3Rpb25zIHsKcHJpdmF0ZToKICBMRUZUIGxlZnQ7CiAgUklHSFQgcmlnaHQ7CnB1YmxpYzoKICBjb21iaW5lX2Z1bmN0aW9ucyhjb25zdCBMRUZUICZsZWZ0LCBjb25zdCBSSUdIVCAmcmlnaHQpCiAgIDogbGVmdChsZWZ0KSwgcmlnaHQocmlnaHQpIHt9CgogIHRlbXBsYXRlIDx0eXBlbmFtZSAuLi5BUkdTPgogIGF1dG8gb3BlcmF0b3IoKShBUkdTJi4uLiBhcmdzKSBjb25zdAogIC0+IGRlY2x0eXBlKGxlZnQoYXJncy4uLiksIHN0YXRpY19jYXN0PHZvaWQ+KHJpZ2h0KGFyZ3MuLi4pKSkKICB7CiAgICBsZWZ0KGFyZ3MuLi4pOwogICAgcmlnaHQoYXJncy4uLik7CiAgfQoKfTsKCi8vSSBzaG91bGQgcHJvYmFibHkgaGF2ZSBhbiBlbmFibGUgaWYgdGhhdCBjaGVja3MgdGhlIGFyZ3VtZW50cyAKLy9hcmUgZnVuY3Rpb24gcG9pbnRlcnMgb3IgZnVuY3RvcnMKdGVtcGxhdGUgPHR5cGVuYW1lIExFRlQsIHR5cGVuYW1lIFJJR0hUPgpjb21iaW5lX2Z1bmN0aW9uczwKICBzdGQ6OmRlY2F5X3Q8TEVGVD4sCiAgc3RkOjpkZWNheV90PFJJR0hUPgo+CmNvbmNhdCgKICBjb25zdCBMRUZUICZsZWZ0LAogIGNvbnN0IFJJR0hUICZyaWdodAopIHsKICByZXR1cm4ge2xlZnQsIHJpZ2h0fTsKfQoKaW50IG1haW4oKQp7CiAgICBjb25jYXQoW10oY29uc3QgYXV0byYgdCkge3N0ZDo6Y291dCA8PCB0O30sCiAgICAgICAgICAgW10oY29uc3QgYXV0byYgdCkge3N0ZDo6Y2VyciA8PCB0O30pCiAgICAgICAgICAgKCJIZWxsbyB3b3JsZCIpOwp9