Jens Weller wrote:
Hi Peter,
yes, I managed to that by now:
#include
#include
#include
struct Widget {};
struct Panel: Widget{Panel(Widget* q){}};
using make_interface = boost::function;
void registerType(const make_interface &make)
{
//factory.register_factory(type_id,make);
}
int main(int argc, char *argv[])
{
auto f = boost::factory();
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::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, 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( 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( f2, _1 ) );
No idea why it needs to be so hard.