I'm trying to create a class which accepts a function as a parameter when it is being initialized. Ideally, the function should already exist. I know that in Python, I can do this:
class TestClass:
def __init__(self, function_parameter):
self.fp = function_parameter
def executeFP(self):
self.fp()
def testFunction():
print("test")
q = TestClass(testFunction)
q.executeFP()
How can I do this in C++? (I'm using an Arduino if it matters)
Arduino doesn't have std::function
, because AVR GCC doesn't ship with the Standard Library, so those suggestions in the comments won't work for that specific platform.
If you need similar behavior for Arduino or other embedded platforms, you can use ETL's etl::function
or etl::delegate
, or create your own implementation. std::function
uses heap allocations for type erasure, which is usually not a good choice for embedded.
The simplest implementation would use C-style function pointers:
// Generic definition of the function type
template <typename F>
class function;
// R: return type
// Args: Any arguments a function can take
template <typename R, typename... Args>
class function<R(Args...)> {
public:
// Type definition of the equivalent C function pointer
using function_type = R (*)(Args...);
// Default constructor: empty function.
// Never call the function while not initialized if using it this way.
function() = default;
// Constructor: store the function pointer
function(function_type f) : function_ptr(f){};
// Call operator: calls the function object like a normal function
// PS: This version does not do perfect forwarding.
R operator()(Args... args) { return function_ptr(args...); }
private:
function_type function_ptr;
};
// A helper function can be used to infer types!
template <typename R, typename... Args>
function<R(Args...)> make_function(R (*f)(Args...)) {
return {f};
}
Live example, with some use cases.
Of course, you can also just use the C pointer for this case, but this class can be extended for other types. If you need more complex behavior, like functors, member functions and capturing lambdas, see ETL's implementations I cited above.