0

.HPP가상 상속, 명시 적 인스턴스화을 돌려 파생 클래스 참조/포인터 (공변 유형)

template <typename T> 
struct A { virtual A& modify() = 0; }; 

template <typename T> 
struct B : virtual A<T> {}; 

template <typename T> 
struct C : B<T> { C& modify() final; }; 

통화 당

template <typename T> 
C<T>& C<T>::modify() { 
    // … 
    return *this; 
} 

// explicit instantiation 
template struct C<double>; 

나는 순서에 대한 참조를 반환하는 몇 가지 방법이 필요합니다 "체인"만들기/대입 연산자/등 정의 :

C<double> a, b, c; 
// …  
a = (b = c).modify(); 

"다이아몬드 문제"(간단히하기 위해 생략)를 피하기 위해 가상 계승을 처리해야합니다.

그러나이 작동하지 않습니다 :

MSVC을 :

Error C2908: explicit specialization; 
'A<T> &C<T>::modify(void)' has already been instantiated 

명시 적 인스턴스화/O를 가상 상속 승 잘 작동합니다. 그래서 여기서 무엇이 잘못되었는지 궁금합니다. (객체 참조/포인터를 돌려주는 멤버 함수가없는 경우에도 모든 것이 잘 작동합니다.)

답변

1

명시 적 인스턴스에 대한 올바른 구문은 다음과 같습니다 또한

template struct C<double>; 
     ^^^^^ 

, 당신은 아직도의 형식 매개 변수를 지정하셔야합니다 C 템플릿 : http://coliru.stacked-crooked.com/a/23ba6a238a7a17da

:

C<double> a, b, c; 
    ^^^^^^ 

적어도 g ++ 및 연타이 코드를 받아

하지만 비주얼 스튜디오는

은 VS는 형태를 돌려 공변 좋아하지 않는 것 같습니다 ...하지 않습니다,/그 소리와 VS 그러나 ++ g에서 다음 컴파일 - 없음 공변 반환 수정() : http://coliru.stacked-crooked.com/a/70c8e64f0824129a

+0

는 이러한 고정 잘못된 인쇄, 고맙습니다. BTW, MSVC는 여전히 당신이주의 한 것처럼 그것을 좋아하지 않습니다. – 56th

+0

@ 56th이 코드는 http://webcompiler.cloudapp.net/에서 http://coliru.stacked-crooked.com/a/70c8e64f0824129a (공변 리턴 값 없음)를 검사하여 컴파일됩니다. – marcinj

+0

고맙습니다. 그러나 ** 파생 된 ** 클래스 참조로 작업하기 때문에 아직 해결책이 아닙니다. "Sliced"객체는 파생 된 객체의 멤버 필드와 아무 관계가 없으므로 ... – 56th