Adam
Adam

Reputation: 1817

No known conversion from unique_ptr, forward declaration?

class Base{};

class C;
class A : Base {
    unique_ptr<Base> x;
    unique_ptr<A> y;

    someMethod (){
        if (sth) {
            x = make_unique<C>(); // error no viable overloaded '=', see below
        }
    }
}

class B : Base {
    A x;
    unique_ptr<B> y;
}

class C : Base {
    B x;
}

How do I solve this? Sizes of the classes should be (are) determinable. That's all I know. I could make the member variables A x and C x as pointers, too, and move B and C above A but I think I would get the same error, but for A.

error: no viable overloaded '='
candidate function not viable: no known conversion from 'unique_ptr<C, default_delete<C>>' to 'unique_ptr<Base, default_delete<Base>>

Upvotes: 1

Views: 3347

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595827

C must be a complete type when calling std::make_unique(), but in your code C has only been forward-declared when std::make_unique() is called, so it doesn't know how large C actually is so it can allocate the std::unique.

Simply move the implementation of A::someMethod() after C has been fully defined (such as to a .cpp file), eg:

class Base {
public:
    virtual ~Base() {}
};

class C;
class A : public Base {
    unique_ptr<Base> x;
    unique_ptr<A> y;

    void someMethod();
};

class B : public Base {
    A x;
    unique_ptr<B> y;
};

class C : public Base {
    B x;
};

...

void A::someMethod()
{
    if (sth) {
        x = make_unique<C>();
    }
}

Upvotes: 2

Related Questions