
Jens Weller wrote:
Hi Peter,
yes, I managed to that by now: #include <boost/function.hpp> #include <boost/functional/factory.hpp> #include <boost/bind.hpp>
struct Widget {}; struct Panel: Widget{Panel(Widget* q){}};
using make_interface = boost::function<Widget*(Widget*)>; void registerType(const make_interface &make) { //factory.register_factory(type_id,make); } int main(int argc, char *argv[]) { auto f = boost::factory<Panel*>(); registerType( boost::bind(f,_1));//< this line is the cause, factory it self compiles }
Thanks Jens. When I try registerType( f ); I get the same error: 1>testbed2015.cpp(6): warning C4100: 'q': unreferenced formal parameter 1>testbed2015.cpp(10): warning C4100: 'make': unreferenced formal parameter 1>c:\Projects\boost-git\boost\boost/function/function_template.hpp(138): error C2664: 'Panel *boost::factory<Panel *,void,boost::factory_alloc_for_pointee_and_deleter>::operator ()(void) const': cannot convert argument 1 from 'Widget *' to 'Widget *&' The problem as far as I can see is that boost::function passes its parameter of type Widget* as an rvalue to its target, rather than as an lvalue, and factory<> takes its arguments by lvalue reference. function's behavior is correct in that if you declare boost::function<void(unique_ptr<X>)>, the argument needs to be passed as an rvalue or it won't work. But it does break code such as the above. Ideally, boost::factory would need to be fixed to use perfect forwarding on C++11 and above. A quick look at its documentation suggests using forward_adapter: auto f2 = boost::forward_adapter<decltype(f)>( f ); registerType( f2 ); // works forward_adapter however doesn't define ::result_type so when you bind it you have to give the type: registerType( boost::bind<Widget*>( f2, _1 ) ); No idea why it needs to be so hard.