문제

C ++에서 함수 템플릿 전문화는 정상적인 기능과 똑같이 작용해야합니다. 그것은 내가 하나의 가상을 만들 수 있다는 것을 의미합니까?

예를 들어:

struct A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

struct B : A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

int main(int argc, char* argv[])
{
    B b;
    A& a = b;
    a.f<int>();
}

Visual Studio 2005 다음 오류를 제공합니다.

치명적인 오류 C1001 : 컴파일러에서 내부 오류가 발생했습니다.

도움이 되었습니까?

해결책

좋은 컴파일러 오류. 이 유형의 수표에 대해 항상 comeau 표준으로 돌아가서 확인하기 전에 컴파일러.

Comeau C/C ++ 4.3.10.1 (2008 년 10 월 6 일 11:28:09) online_evaluation_beta2 Copyright 1988-2008 Comeau Computing. 판권 소유. 모드 : 엄격한 오류 C ++ C ++ 0x_extensions

"comeautest.c", 3 행 : 오류 : 함수 템플릿 선언 템플릿에서 "가상"이 허용되지 않습니다. 가상 void f (); ^

"comeautest.c", 10 행 : 오류 : 함수 템플릿 선언 템플릿에서 "가상"이 허용되지 않습니다. 가상 void f (); ^

이제 다른 사용자가 게시 한 것처럼 표준은 가상 템플릿 메소드를 정의 할 수 없다는 사실입니다. 이론적 근거는 모든 가상 방법의 경우 VTABLE에 항목을 예약해야한다는 것입니다. 문제는 템플릿 메소드가 인스턴스화 된 경우에만 정의된다는 것입니다. 즉, VTABLE은 각 호출 수에 따라 각 컴파일 장치에 다른 수의 요소를 갖게됩니다. 에프() 다른 유형이 발생합니다. 그러면 지옥이 자랄 것입니다 ...

당신이 원하는 것이 인수 중 하나에 대한 템플릿 함수이고 하나의 특정 버전이 가상 (인수의 일부 참고)이라면 다음을 수행 할 수 있습니다.

class Base
{
public:
   template <typename T> void f( T a ) {}
   virtual void f( int a ) { std::cout << "base" << std::endl; }
};
class Derived : public Base
{
public:
   virtual void f( int a ) { std::cout << "derived" << std::endl; }
};
int main()
{
   Derived d;
   Base& b = d;
   b.f( 5 ); // The compiler will prefer the non-templated method and print "derived"
}

어떤 유형에 대해서도이 일반화를 원한다면 운이 좋지 않습니다. 다형성 대신 다른 유형의 대표단을 고려하십시오 (집계 + 대표단은 해결책이 될 수 있음). 당면한 문제에 대한 자세한 정보는 솔루션을 결정하는 데 도움이됩니다.

다른 팁

에 따르면 http://www.kuzbass.ru:8086/docs/isocpp/template.html ISO/IEC 14882 : 1998 :

-3- 멤버 함수 템플릿은 가상이 아닙니다.

예시:

template <class T> struct AA {
    template <class C> virtual void g(C);   //  Error
    virtual void f();                       //  OK
};

다른 사람들이 언급했듯이 회원 기능 템플릿을 선언 할 수 없기 때문에 이것은 법적 코드가 아닙니다. virtual.

그러나 Visual Studio 2012조차 이것에 대해 질식합니다.C++ internal compiler error on Visual Studio 2012 전체 크기를 보려면 여기를 클릭하십시오

이벤트 로그는 컴파일러가 충돌했음을 나타냅니다 0xC0000005, 또는 STATUS_ACCESS_VIOLATION. 특정 (불법) 코드 구성이 컴파일러를 Segfault로 만드는 방법은 재밌습니다 ...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top