templates - How do I generalize calling a list of functions in C++? -
i have following code allows me instantiate , call list of void()
functions.
(i using https://github.com/philsquared/catch unit testing if wish compile , run code).
#include "catch.hpp" #include <functional> #include <vector> class chainofresponsibility : public std::vector<std::function<void()> >, public std::function<void()> { public: void operator()() const { for(std::vector<std::function<void()> >::const_iterator = begin(); != end(); ++it) { (*it)(); } } }; test_case("chainofresponsibility calls members when invoked") { bool test_function_called = false; std::function<void()> test_function = [&]() { test_function_called = true; }; chainofresponsibility object_under_test; object_under_test.push_back(test_function); object_under_test(); require(test_function_called); }
my question how template chainofresponsibility
class accept functions different (but consistent) signature?
for example, consider chainofresponsibility<void(int)>
or chainofresponsibility<returnclass(argument1class, argument2class)>
.
for sake of argument, lets second example returns value returned last member in chain, or default value returnclass if chain empty.
also, if stl contains template class achieves this, prefer use on home-grown class.
your specific "discard intermediate results" simple, think it's bad idea.
template<typename ret, typename ... args> class chainofresponsibility { std::vector<std::function<ret(args...)> > chain; public: ret operator()(args ... args) const { ret value; for(auto & func : chain) { value = func(args...); } return value; } };
void
has treated on it's own
template<typename ... args> class chainofresponsibility<void, args...> { std::vector<std::function<void(args...)> > chain; public: void operator()(args ... args) const { for(auto & func : chain) { func(args...); } } };
note deriving std::
types bad idea, std::function
, type-erasing callable, not "the base of callables". can provide operator()
options improving non-void case:
// fold results template <typename binaryfunction> ret operator()(args ... args, binaryfunction add, ret init) const { for(auto & func : chain) { init = add(init, func(args...)); } return init; } // return vector template <typename binaryfunction> std::vector<ret> operator()(args ... args) const { std::vector<ret> results(chain.size()); for(auto & func : chain) { results.push_back(func(args...)); } return results; }
Comments
Post a Comment