2017-12-18 17 views
0
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; 
} 

どうすれば解決できますか?クラスのサイズは決定可能でなければならない。それが私の知る全てだ。私も、ポインタとしてメンバ変数A xC xを行い、Aの上にBとCを動かすが、私は同じエラーを取得すると思いますが、呼び出すときにAのunique_ptrからの変換はありません。

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>> 
+0

ます。また、[CRTP]使用することができます。

単にCA::someMethod()の実装を移動するには、完全例えば、(例えば.cppファイルとして)定義されています/ wiki/Curiously_recurring_template_pattern)。 – Eljay

+0

私がテストした回答がなぜ削除されたのですか? C言語の後にA :: someMethodを定義する必要があると言いました。 – Adam

+1

Um ...ここではいくつかの問題がありますが、 'Base'は' C'の* private *ベースなので、これはコンパイルする機会はありません。 – AnT

答えて

1

Cは完全な型でなければなりませんでしたstd::make_unique()であるが、Cのコードでは、std::make_unique()が呼び出されたときにのみ前方宣言されているため、Cの実際のサイズがわからないので、std::uniqueを割り当てることができます。 https://en.wikipedia.org(

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>(); 
    } 
} 
+0

最初の文は実際には真実ではありません。 'std :: make_unique'のインスタンス化は、インスタンスを割り当てて構築するために' C'の完全な定義を見る必要がありますが、 'std :: make_unique'の呼び出し側はそれを必要としません。したがって、なぜ 'unique_ptr ' - > 'unique_ptr '変換についてのエラーメッセージが 'new C {}'割り当てではないのかという理由でエラーメッセージが出されます。コンパイラは 'make_unique ()'の暗黙的なインスタンス生成を失敗しますが、それは致命的ではありません。リンカーは、プログラム内のどこか他の場所で有効なインスタンス化(明示的な場合もある)が提供されている場合に、 –

関連する問題