|
Boost : |
From: Yitzhak Sapir (yitzhaks_at_[hidden])
Date: 2002-05-23 04:49:35
I would like to use boost::thread, which takes a function0 parameter. Now, I have a class that maintains data for the thread that should be accessible from other objects in the system. I would like to declare a function in this class that symbolizes the thread function. Using boost::bind and calling the functions any of various common names (such as "Run", "Work", "ThreadFunction", "Thread", "work", etc.) for such a function works fine.
However, it might have been cleaner to name this function operator()(...), which, being the function operator, would describe the functionality of the class, rather than some arbitrary name that is based on the current mood and vocabulary of the programmer. What's more, boost::thread, expects a functor to be passed to it. I could pass the class to boost::thread directly like this: new boost::thread(*this), eliminating the call boost::bind altogether, but then I'd probably invoke a copy constructor and pass a copy of this class, if this class is even copyable. Using boost::thread(boost::ref(*this)) is not possible because ref() cannot know which return types to define for possible operator() calls.
However, it would have been possible to simply say new boost::thread(this). This would invoke the instantiation of boost::function0 that takes a " typename Function * " as a parameter. This Function* would in this case be a pointer to functor rather than a pointer to function. The only thing that seems to prevent this is calls like this (I am using boost 1.26/7 in this case, but from looking at the cvs it seems this comment still applies).
static unusable invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS)
{
FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
f(BOOST_FUNCTION_ARGS);
return unusable();
}
rather than
static unusable invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS)
{
FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
(*f)(BOOST_FUNCTION_ARGS);
return unusable();
}
It seems that this function always calls a function pointer, based on the identifiers specified in this function. I assume in the case of a function object we would go to BOOST_FUNCTION_FUNCTION_OBJ_INVOKER rather than a function pointer invoker. But I am definitely not aware of all the tiny details of boost::function.
In the application I described, the latter is more robust and general since it allows pointers to functions as well as pointers to functors and provides a simple solution to passing a functor itself by reference rather than a copy of the functor. This has applications beyond what I have described above and multithreading, but I wanted to give the example that led me to suggest this.
So basically I am asking for comments regarding any step in the above logic. For example, maybe it's a bad idea altogether for other reasons to use operator()() as the thread function, or maybe this "generality" I have suggested is not so general and prevents using other legal constructs with boost::function. Also, if the comments are by chance all positive, to make a suggestion to use the code I have proposed?
Going back to boost::bind, if the logic holds for boost::function, then being able to use pointers to functors as the functional parameters to boost::bind would also be useful.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk