Re: passing functor or function to template class
If you happen to have TR1 libs, it is actually even
more simple (would be the same with C++11):
....
Hmm - I'm not sure if I find that more simple :-), but that's maybe because I'm still not too much into the new C++0x standard.
My only concern with these solutions that they store
everything as reference, thus disallow one of the most
frequent use of functors (passing them as temporary rvalue).
That's right, the library user should know wheather she has to take care of object lifetime. But using the tr1::function framework as you suggested earlier would overstrain my (local) users of the library.
But how about the following sample implementation, where the library user may pass function pointers and copyable objects by value and noncopyable objects by pointer?:
/*****************/
/* Library code: */
/*****************/
#include <iostream>
template<typename T> struct IsPointer {
IsPointer(T f):f(f) {}
T &f;
};
template<typename T> struct IsPointer<T *> {
IsPointer(T *f):f(*f) {}
T &f;
};
// Some generic library function accepting
// all sorts of callable objects.
template<typename Callable> void print(Callable func) {
IsPointer<Callable> p(func);
std::cout << p.f() << std::endl;
// But how can an assignment like the
// following be made to work for all
// types of callable objects?
//Callable *x = &(p.f);
}
/*********************/
/* Application code: */
/*********************/
// A function.
const char *function() {return "function";}
// A copyable functor.
struct CopyableFunctor {
const char *operator()() {return "copyable functor";}
} copyableFunctor;
// A noncopyable functor.
class NonCopyableFunctor {
public:
NonCopyableFunctor() {}
const char *operator()() {return "noncopyable functor";}
private:
NonCopyableFunctor(const NonCopyableFunctor &);
} nonCopyableFunctor;
// Test it:
int main() {
print(function);
print(copyableFunctor);
print(&nonCopyableFunctor);
return 0;
}
Note that I switched to a function template for the "library interface" to show that template deduction works fine as well. The only concern with this approach
is pointed out in the code comments above: How may I make assignments with my callable objects that work for all types (i.e. funtions, functors and pointers to functors)?
Cheers,
Chris