'템플릿'에 대한 기반에서 파생 클래스로 'typedef'전파
typedef 만 포함하는 기본 클래스를 정의하려고합니다.
template<typename T>
class A
{
public:
typedef std::vector<T> Vec_t;
};
template<typename T>
class B : public A<T>
{
private:
Vec_t v; // fails - Vec_t is not recognized
};
BI에서 Vec_t가 인식되지 않고 명시 적으로 작성해야한다는 오류가 발생하는 이유는 무엇입니까?
typename A<T>::Vec_t v;
이 질문이 중복 된 것 같지만 지금은 찾을 수 없습니다. C ++ Standard는 14.6.2 / 3에 따라 이름을 정규화해야한다고 말합니다.
클래스 템플릿 또는 클래스 템플릿의 멤버 정의에서 클래스 템플릿의 기본 클래스가 template-parameter에 의존하는 경우 클래스 정의 시점에서 정규화되지 않은 이름 조회 중에 기본 클래스 범위가 검사되지 않습니다. 템플릿 또는 멤버 또는 클래스 템플릿 또는 멤버의 인스턴스화 중에.
UPD : 마침내 중복을 찾았습니다. 여기 있습니다 .
템플릿의 경우 종속 및 비 종속 이름 이라는 것이 있습니다 .
이름이 템플릿 매개 변수 T에 종속 된 경우 해당 종속 이름과 매개 변수 T에 종속 되지 않는 다른 이름 은 독립된 이름입니다.
규칙은 다음과 같습니다. 컴파일러는 비 종속 이름 (예 : Vec_t)을 찾을 때 종속 기본 클래스 (예 : A)를 찾지 않습니다. 결과적으로 컴파일러는 유형은 고사하고 존재조차 알지 못합니다.
어디가 데이터 멤버 인지에 대한 잠재적 전문화 Vec_t
가 T
있기 때문에 컴파일러는 알 때까지 유형 이라고 가정 할 수 없습니다.A<T>
A<T>:: Vec_t
그래서 해결책은 typename을 사용하는 것입니다.
typename A<T>::Vec_t v; ← good
이 https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-types 를 살펴 보는 것이 좋습니다 .
이전 (깨진) 링크 : http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18
컴파일러 Vec_t
는 유형의 이름을 확실하지 않기 때문 입니다. 예를 들어, A<T>
대한 전문 수 있습니다 T=int
에 없는 특정 있습니다 typedef
.
완전성을 위해 다음과 같이 이러한 성가신 문제를 완화 할 수있는 방법이 있습니다.
- 파생 클래스에서 해당 유형을 다시 typedef하거나 메소드와 마찬가지로 더 좋습니다.
- 다음과 같이 파생 클래스 범위에서 해당 이름을 가져옵니다
using declaration
.
template<typename T>
class A
{
public:
typedef std::vector<T> Vec_t;
};
template<typename T>
class B : public A<T>
{
public:
using typename A<T>::Vec_t;
// .........
private:
Vec_t v;
};
typedef
파생 클래스에서 상속 된 항목 에 대해 둘 이상의 언급이있는 경우 유용 할 수 있습니다 . 또한 typename
매번 추가 할 필요가 없습니다 .
Vec_t
컴파일러가 어디에서 Vec_t
오는지 알지 못하기 때문에 의 사용을 명시 적으로 한정해야합니다 .
It cannot assume anything about the structure of A, since the class template A may be specialized. The specialization may include a Vec_t
which is not a typedef, or it may not even include a member Vec_t
at all.
Vec_t is not a dependent name, and the compiler needs to know what it is without instantiating any templates (base class in this case). It is really no different from:
template <class T>
class X
{
std::string s;
}
Here as well the compiler needs to know about std::string even if X is not instantiated, since the name does not depend on the template argument T (as far as the compiler can assume).
All in all, typedefs in a template base class seem rather useless for use in derived class. The typedefs are useful for the user, however.
This concept can be associated with how we use std::vector<T>
. For example, if we have a std::vector<int> Foo
. Now, we decide to use any of it's member types, lets say an iterator
. In this scenario we explicitly mention
std::vector<int>::iterator foo_iterator;
Similarly in your case, in order to use a public member type Vec_t
of template <typename T> class A
, you need to explicitly declare it as
A<T>::Vec_t v;
OR
A<int>::Vec_t int_type;
'Programing' 카테고리의 다른 글
Winforms 문제-창 핸들 생성 오류 (0) | 2020.12.05 |
---|---|
Swing Java에서 JFrame 모달을 만드는 방법 (0) | 2020.12.05 |
Javascript로 GIF 애니메이션을 제어 할 수 있습니까? (0) | 2020.12.05 |
새 노드가 DOM에 삽입 될 때 발생하는 jquery 이벤트가 있습니까? (0) | 2020.12.05 |
AsyncTask : doInBackground ()의 반환 값은 어디로 가나 요? (0) | 2020.12.05 |