2012-04-16 2 views
5

내가 this->를 사용하지 않는 경우템플릿 클래스 인 상위 클래스의 변수를 사용할 수없는 이유는 무엇입니까?

template <typename T> 
class B : public A<T> 
{ 
    public: 
    int f(); 
} 

template <typename T> 
int B<T>::f() 
{ 
    int t; 
    t = this->a; //Okay 
    t = a //Error 
    return 0; 
} 

왜 오류가 발생합니까 b.h

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

a.h?

어떤 방법으로 this->을 생략해도됩니까?

은 템플릿 인스턴스화 ("2 단계 이름 조회")의 두 단계가 있습니다

+0

요아킴 말보로가 대답을주었습니다. 그 외에도, 제공된 코드에는 컴파일하는 것을 방해하는 다른 문제가 있습니다. – Anonymous

+0

이것이 실제 코드입니까?'int B 에 대한 클래스 정의와 스코프 연산자 뒤에는 뒤에 오는 세미콜론이 없습니다 : f()'는 오류 라인에 세미콜론을 더한 것이 아니라 부정확합니다. – hmjd

+0

오, 그냥 타이핑 실수 일뿐입니다. 나는 그것을 고쳤다. –

답변

11

(나는 몇 가지 실수를 고정).

첫 번째 단계에서 모든 종속되지 않는 이름이 확인됩니다. 두 번째 단계에서는 종속 이름이 확인됩니다.

종속 이름

지금, 당신이 쓰는 템플릿 매개 변수에 따라 이름, 예컨대 :

template <typename T> 
void foo() { 
    x = 0; // <- Non-dependent, nothing in that refers to "T". 
       // Thus looked up in phase 1, therefore, an 'x' must be 
       // visible. 

    T::x = 0; // <- Dependent, because it depends on "T". 
       // Looked up in phase 2, which is when it must be visible. 
} 

입니다 :

t = this->a; //Okay 
t = a //Error 

이 내가 설명 정확히 것입니다. 괜찮은 용어 인 경우 t은 2 단계에서 으로 조회됩니다. this은 템플릿 매개 변수에 따라 달라지기 때문입니다.

해당 이름의 아무 것도 템플릿 매개 변수에 의존하지 않으므로 잘못된 용어는 1 단계에서 조회됩니다. 템플릿을 특수화 할 수 있고 기본 템플릿 선언에서 원격 일 수있는 , 다른 전문화 인 은 템플릿이 특수화 될 수 있기 때문에 컴파일러에서 기본 클래스 템플릿 을 인트로 스콥 할 수 없으므로 1 단계에서 컴파일러가 a을 볼 수 없습니다. a이 표시되지 않을 수 있습니다.

예 :

template <typename T> 
    struct Base { 
    }; 


    template <typename T> 
    struct Derived : Base<T> { 
     void foo() { 
      this->a = 0; // As is valid. `this->a` is looked up in phase 2. 
     } 
    }; 


    template <> struct Base<int> { 
     int a;    
    }; 


    int main() 
    { 
      // The following declarations trigger phase 2 lookup. 

      Derived<int> di; // valid, because a later specialized 
           // Base<int> is used and all symbols 
           // are resolved. 

      Derived<float> df; // not valid 
    } 

, BTW 내가 한 번 내 매우 낮은 주파수 블로그에 this-> is not only a matter of style를 작성했습니다.

+0

종속 이름은 템플릿 매개 변수에 종속되지 않는 이름입니다. -> 종속 이름은 템플릿 매개 변수에 의존하는 이름입니다.) – czxyl

+0

@czxyl :이 실수를 발견하는 데 약 반세기 : D 힌트를 주셔서 감사합니다.) –

1

B은 템플릿이므로 인스턴스 이름이 아닌 템플릿이 정의 될 때 해당 이름이 조회되어야합니다. 그러나 템플릿을 정의 할 때 종속 이름은 알지 못합니다 (기본 클래스 템플리트 A의 특수화가 아직까지 없었 음). 컴파일러는 정규화되지 않은 이름을 기본 클래스로 해석 할 수 없습니다.

template <typename T> 
class B : public A<T> 
{ 
    public: 
    using A<T>::a; 
    int f(); 
}; 

는 또한 누락 클래스 선언 후 세미콜론과 선으로 표시 위치를주의 : 당신은 A<T>::으로 또는 using 선언을 접두사로, this-> 자격을 통해 현재 범위에 이름을 가져올 수 있습니다 // Error 댓글

+0

"종속 이름을 알 수 없습니다"-> 이것은 C++ 용어로는 이해가되지 않습니다. 이름은 의존적 일 수도 있고 그렇지 않을 수도 있습니다. typename T로'A :: x'는 의존적 인 이름이고'x'는 그렇지 않습니다. 프로그래머가'x'가 의존적 인 이름이지만, 기술적으로'x'는 의존적 이름이 아닙니다. –

+0

-1 : "이름이 종속적이어서 결과적으로 조회해야합니다"-> 잘못된 것입니다. 의존하는 회원 이름이있을 수 있습니다. 예 : http://ideone.com/zIa7k –

+0

-1 :'this->'는 to와 아무 관련이 없습니다. –

관련 문제