2017-12-18 23 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 x 포인터로 C x을, 그리고 위의 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 파일로) 정의 된/위키/Curiously_recurring_template_pattern). – Eljay

+0

내가 테스트 한 답변이 왜 삭제 되었습니까? 그것은 C 후에 A :: someMethod를 정의 할 필요가 있다고 말했습니다. – Adam

+1

음 ... 여기에는 몇 가지 문제가 있지만, Base는'C'의 private * 기반이기 때문에 컴파일 할 기회가 없습니다. – AnT

답변

1

C는 완전한 유형이어야 수 std::make_unique()하지만 코드 Cstd::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 ()'의 암시 적 인스턴스 생성을 실패하지만 치명적이지는 않습니다. 링커는 프로그램의 다른 곳에서 유효한 인스턴스화 (명시적일 수도 있음)를 제공하면 링커가 해결할 수있는 참조를 방출합니다. –