Style Case Studies: Generic Callbacks - More Style Improvements
(Page 3 of 5 )
While we’re already beating on the poor execute function, there’s an arguably more serious idiomatic problem:
6. (Idiom) And the execute function should be spelled operator(). In C++, it’s idiomatic to use the function-call operator for executing a function-style operation. Indeed, then the comment, already somewhat redundant, becomes completely so and can be removed without harm because now our code is already idiomatically commenting itself. To wit:
void operator()() const { (object.*F)(); } // launch callback function
“But,” you might be wondering, “if we provide the function-call operator, isn’t this some kind of function object?” That’s an excellent point, which leads us to observe that, as a function object, maybe callback instances ought to be adaptable too.
Guideline: Provide operator() for idiomatic function objects rather than providing a named execute function.
Pitfall: (Idiom) Should this callback be derived from std::unary_function? See Item 36 in [Meyers01] for a more detailed discussion about adaptability and why it’s a Good Thing in general. Alas, here, there are two excellent reasons why callback should not be derived from std::unary_function, at least not yet:
- It’s not a unary function. It takes no parameter, and unary functions take a parameter. (No, void doesn’t count.)
- Deriving from std::unary_function isn’t going to be extensible anyway. Later on, we’re going to see that callback perhaps ought to work with other kinds of function signatures too, and depending on the number of parameters involved, there might well be no standard base class to derive from. For example, if we supported callback functions with three parameters, we have no std::ternary_function to derive from.
Deriving from std::unary_function or std::binary_function is a convenient way to give callback a handful of important typedefs that binders and similar facilities often rely upon, but it matters only if you’re going to use the function objects with those facilities. Because of the nature of these callbacks and how they’re intended to be used, it’s unlikely that this will be needed. (If in the future it turns out that they ought to be usable this way for the common one- and two-parameter cases, then the one- and two-parameter versions we’ll mention later can be derived from std::unary_function and std::binary_function, respectively.)
This chapter is from Exceptional C++ Style, by Herb Sutter (ISBN 0201760428, copyright 2005. All rights reserved. It is reprinted with permission from Addison-Wesley Professional). Check it out at your favorite bookstore today.
Buy this book now. |
Next: Correcting Mechanical Errors and Limitations >>
More Code Examples Articles
More By Addison-Wesley/Prentice Hall PTR