Passing Function Object: Error

What happened to the next little program that passes an object to a function?

#include <iostream> #include <functional> void foo(const std::unary_function<const std::string&, void>& fct) { const std::string str = "test"; fct(str); // error } class MyFct : public std::unary_function<const std::string&, void> { public: void operator()(const std::string& str) const { std::cout << str << std::endl; } }; int main(int argc, char** argv){ MyFct f; foo(f); return 0; } 

I get the following error on line 6:

  no match for call to `(const std::unary_function<const std::string&, void>) (const std::string&)' 
+4
source share
1 answer

A common mistake. unary_function and binary_function are just two structures that add typedefs

 argument_type result_type 

and correspondingly

 first_argument_type second_argument_type result_type 

Not more. They are intended for the convenience of creators of object object types, so they do not need to do this themselves. But they do not behave polymorphically. What you want is a wrapper on the objects of the object. boost::function comes to mind:

 void foo(boost::function<void(const std::string&)> const& fct) { const std::string str = "test"; fct(str); // no error anymore } 

Or make it a template

 template<typename FunctionObject> void foo(FunctionObject const& fct) { const std::string str = "test"; fct(str); // no error anymore } 

You can take it by value and then return a copy from foo if you use it to apply it to some sequence. This will allow the function object to update some state variables among its members. for_each is an example that he likes. In general, in any case, I would accept them at a cost, because they are usually small, and copying them provides great flexibility. So what i do

 template<typename FunctionObject> void foo(FunctionObject fct) { const std::string str = "test"; fct(str); // no error anymore } 

Then you can take a copy of fct and save it somewhere, and fct operator () may not be constant and update some elements (which is part of the whole point of operator() ). Remember that if you use an object object via a const reference, you cannot copy it at all, because the user could pass a function. Then the copy will try to locally declare the function instead of the local function pointer. However, when accepting the default value, a pointer to the function is accepted when the function is passed, which can be safely copied.

+11
source

All Articles