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();