Below C++11 code won't compile (should work to my first impression) under g++ 4.9.2:
class A{};
class B : public A{};
void func(shared_ptr<B>){}
TEST(testFunc, testFunc_conv){
std::function<void(shared_ptr<A>)> afunc;
afunc = func;
}
The error messages indicate it doesn't accept the conversion from shared_ptr<B>
to shared_ptr<A>
though those B
can be converted to A
.
Why doesn't this work? Is it possible to work around this limitation?
EDIT I consider the implications carefully and understand the reason - A can't be converted to B indeed, so it's not allowed for the sake of type safety.
The background of this code is to implement some generic interface with variadic parameters, so other part of the world can register a callable that taking derivatives of an empty base type. The callable would be called later (kind of deferred call):
//action would be stored for deferred call
// when action is actually called, it will use the real type
template<class ObjType>
registerInterface(function<void(Base*)> action, ObjType* obj){
function<void()> callable = [=]{ action(obj);}
//callable action would be stored for deferred call
}
void interfaceImpl(Derived* d){
d->realOperation();
}
//do registration - need to do the conversion each time for each interface implementation!
Derived d;
registerInterface(interfaceImpl, &d);
It would be annoying for each interfaceImpl
to declare as taking the base type and do the downcasting brutely.
My solution is to remove the function from interface and set a implicit callable template argument for interfaceImpl
to specify. Appreciate if there're better solutions.