문제

다음 코드를 컴파일하지 않으로 gcc 지만,Visual Studio:

template <typename T> class A {
public:
    T foo;
};

template <typename T> class B: public A <T> {
public:
    void bar() { cout << foo << endl; }
};

오류를 얻을:

test.cpp:회원 기능'void B::bar()':

테스트입니다.cpp:11:오류:'foo'지 선언에서 이 범위

그러나 이어야 한다!변경하는 경우 bar 하기

void bar() { cout << this->foo << endl; }

다음 컴파일하지만,나는 생각하지 않는 이것을 해야 한다.무언가가 있는가에서는 공식 사양의 C++는 GCC 는 다음과 같은 여기에,또는 그것이 바로 특질?

도움이 되었습니까?

해결책

이에서 변경 gcc-3.4.C++파서 훨씬 더 엄격한에서는 출시당 spec 지도가 가진 사람들을 위해 기존 또는 멀티 플랫폼의 코드를 기지.

다른 팁

다윗은 이너했고,역사에 바로 그 이유가 여기 있습니다.

문제를 컴파일하는 경우 B<T> 는 기본 클래스 A<T> 는 알 수 없는 컴파일러에서는 템플릿 클래스,그래서 어떠한 방식으로를 위한 컴파일러 알고 있는 멤버에서 기본 클래스입니다.

이전 버전의 어떤 유추하여 실제로 구문 분석의 기본 템플릿 클래스,하지만 ISO C++는 이 추정생할 수 있습 충돌이 있어야 합니다.

이 솔루션을 참조 기본 클래스의 구성원에서는 템플릿을 사용하는 것입 this (사)또는 특별히 이름을 기본 클래스:

template <typename T> class A {
public:
    T foo;
};

template <typename T> class B: public A <T> {
public:
    void bar() { cout << A<T>::foo << endl; }
};

더 많은 정보에 gcc 설명서.

Wow.C++지를 놀라게 중단하이 나와 있습니다.

에서는 템플릿 정의,자격이 없는 이름을 더 이상 회원의 종료(에 의해 지정된[temp.dep]/3 에서는 C++표준).예를 들어,

template <typename T> struct B {
  int m;
  int n;
  int f ();
  int g ();
};
int n;
int g ();
template <typename T> struct C : B<T> {
  void h ()
  {
    m = 0; // error
    f ();  // error
    n = 0; // ::n is modified
    g ();  // ::g is called
  }
};

해야 합니다 이름을 따라,예를 들어,에 의해 붙들이 이->.여기에는 수정된 정의의 C:h,

template <typename T> void C<T>::h ()
{
  this->m = 0;
  this->f ();
  this->n = 0
  this->g ();
}

에 대한 대안으로 솔루션(불행하게도의 호환이 되지 않으로 GCC3.3),사용할 수 있습을 사용하여 선언을 대신 이->:

template <typename T> struct C : B<T> {
  using B<T>::m;
  using B<T>::f;
  using B<T>::n;
  using B<T>::g;
  void h ()
  {
    m = 0;
    f ();
    n = 0;
    g ();
  }
};

는 모든 종류의 미쳤다.감사,데이비드습니다.

여기에는"온도입니다.dep/3"섹션의 표준[ISO/IEC14882:2003]그들은 그를 참조하기:

의 정의에서는 템플릿 클래스의 구성원 또는 템플릿 클래스 경우,기본 클래스의 템플릿 클래스에 따라 템플릿을 매개변수,기본 클래스의 범위는 검사하지 않습니다 동안 자격이 없는 이름을 조회 하거나 시점에서 클래스의 정의 템플릿 또는 멤버 중 또는 인스턴스화의 클래스 템플릿을 사용하거나 또는 회원입니다.[예:

typedef double A; 
template<class T> class B { 
    typedef int A; 
}; 
template<class T> struct X : B<T> { 
    A a; // a has typedouble 
}; 

이름 유형 A 에서 정의 X<T> 에 바인딩하 typedef 이름에서 정의된 글로벌 네임스페이스의 범위가 아닌 typedef 이름에서 정의한 기본 클래스 B<T>.][예:

struct A { 
    struct B { /* ... */ }; 
    int a; 
    int Y; 
}; 
int a; 
template<class T> struct Y : T { 
    struct B { /* ... */ }; 
    B b; //The B defined in Y 
    void f(int i) { a = i; } // ::a 
    Y* p; // Y<T> 
}; 
Y<A> ya; 

구성원 A::B, A::a, 고 A::Y 템플릿의 인수 A 에 영향을 미치지 않습의 결합에 이름 Y<A>. ]

주된 이유는 C++수 없다고 가정 아무것도 여기는 기본 템플릿 수 있는 전문화한 유형에 대한 후입니다.계속되는 원래 예제:

template<>
class A<int> {};

B<int> x; 
x.bar();//this will fail because there is no member foo in A<int>

VC 지 않 구현상을 조회하는 동안,GCC 않습니다.그래서 GCC 분석 템플릿을 하기 전에 그들은 인스턴스화하고 따라서 발견하는 것보다 많은 오류가 VC.에를 들어,foo 이 의존하는 이름,이후에 따라 달라집'T'.지 않는 한 당신이 컴파일러 그것이 어디에서 오는 그것의 유효성을 확인할 수 없습니다 템플릿에서 모든기 전에,인스턴스화할니다.그 이유는 당신을 말할 수 있는 컴파일러는 그것에서 비롯됩니다.

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