Re: What's a good, modern (c++11) argument type for a callback function?
Hello Group!
On Friday, October 25, 2013 1:40:01 AM UTC-4, ?? Tiib wrote:
On Friday, 25 October 2013 02:53:32 UTC+3, K. Frank wrote:
If I am writing a function (or a class) that gets
passed in a user-provided callback function, what
would be a good, general-purpose choice for the
argument type of the callback function?
If possible, use template for such callable argument:
template <typename Function>
void ApplyMeaning(Function f) { f(42); }
Rationale is that compiler may find more ways to optimize or inline that.
Would this be a good use of std::function?
There are situations when templates can not be used. If there are
different callables that must be called uniformly but type of
callable may be unknown then std::function makes sense.
For example, let's say that my callback function
takes a string and returns a bool. Would something
like
void registerCallback (std::function<bool (std::string)> &cb);
make sense?
Reference of std::function does only make sense if you have some
(undescribed here) external logic that the reference stays valid
until used.
Other choices? Better choices?
Like always the design matters and we do not have silver bullet
solutions that fit for every design.
Thanks for everyone's answers and suggestions.
I guess in my own mind, I summarize it like this:
1) std::function is perfectly reasonable to use for
callbacks:
void registerCallback (std::function<bool (std::string)> cb);
Possible issues: std::function has value semantics, making
it less convenient to pass in callback objects by reference
(although std::reference_wrapper can be used). Possible
efficiency of templates is lost.
2) You can templatize on the specific type of the callback:
template<typename CallbackType>
void registerCallback (CallbackType cb);
Possible issues: Absent concepts (or comments in the code)
the requirements of a CallbackType (e.g., the signature of
the callback function) are not made explicit in the interface.
Requires that the actual type of the callback be known at
compile time. (Introduces standard disadvantages of templates.)
3) Derive callbacks from a base callback interface class:
class Callback {
public:
bool operator() (std::string) = 0;
};
void registerCallback (Callback& cb);
Possible issues: Requires that callbacks be derived
from a common base class. Callbacks cannot be passed
by value -- must be passed polymorphically by pointer or
reference. (Introduces standard costs of polymorphism.)
(As ?? said, we have no one silver bullet.)
Thanks for everyone's insight.
K. Frank
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]