Cause of the error
This is because the multiple inheritance here:
class B : A, public Buildable<B>{};
It causes class B
to inherit from Buildable<A>
and from Buildable<B>
which both contain a buildObject()
overload. Unfortunately, both overloads differs only by the return type. This is not allowed.
Design issue
Unfortunately, you can't avoid this unless you could smuggle an additional parameter to buildObject()
, which could permit the compiler to use proper type derivation to resolve avoid ambiguity.
But do you really intend to have multiple inheritance in your design here ? If your classes would be polymorphic, couldn't you use a class B defined as follows:
class B : public A {}; // inherits from Buildable A
...
QSharedPointer<A> b = B::buildObject(); //
Alternative design
The alternative could be to put the building class at the bottom of the derivation, to avoid the conflicts. Make your constructors for classes A and B protected, and use this template class :
// (I used here shared_ptr instead of QSharedPointer for testing purpose)
template <typename T>
class Builder : public T
{
public:
Builder() = delete;
Builder (const Builder&) = delete;
template<typename ...Args>
static shared_ptr<T> buildObject(Args&&... all)
{
return make_shared<T>(std::forward<Args>(all)...) ;
}
};
class A { };
class B : public A {}; // Normal class hierarchy.
// can't be instantiated if ctor are protected.
shared_ptr<A> a = Builder<A>::buildObject();
shared_ptr<B> b = Builder<B>::buildObject();