문제

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에 따라 이름을 완전히 평가해야한다고 말합니다.

클래스 템플릿 또는 클래스 템플릿의 구성원의 정의에서 클래스 템플릿의 기본 클래스가 템플릿 부문에 의존하는 경우 기본 클래스 범위는 자격이없는 이름 조회 중에 검사되지 않습니다. 클래스 템플릿 또는 멤버의 정의 시점 또는 클래스 템플릿 또는 멤버의 인스턴스화 중.

upd : 마지막으로 중복을 찾았습니다. 여기있어.

다른 팁

의존하는 것이 있습니다 비 의존적 템플릿의 경우 이름.

이름이 템플릿 매개 변수 t에 의존하는 경우 매달린 이름과 다른 사람은 매개 변수 t에 의존하지 않습니다. 독립적인 이름.

규칙은 다음과 같습니다. 컴파일러는 vec_t와 같은 의존적 이름을 찾을 때 종속 기본 클래스 (a)를 보지 않습니다. 결과적으로, 컴파일러는 유형이라도 존재한다는 것을 알지 못합니다.

컴파일러는이를 가정 할 수 없습니다 Vec_t 알 때까지 유형입니다 T 잠재적 인 전문화가 있기 때문입니다 A<T> 어디 A<T>:: Vec_t A는 데이터 구성원입니다

따라서 솔루션은 타이프 이름을 사용하는 것입니다

 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.

완전성을 위해,이 성가심을 조금만 완화 할 수있는 방법은 다음과 같습니다.

  • 메소드와 마찬가지로 파생 클래스 또는 더 나은 유형의 유형을 Reypedef -
  • 파생 클래스 범위에서 해당 이름을 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 에서 오는.

클래스 템플릿 A가 전문화 될 수 있으므로 A의 구조에 대해 아무것도 가정 할 수 없습니다. 전문화에는 a가 포함될 수 있습니다 Vec_t typedef가 아니거나 회원을 포함하지 않을 수도 있습니다. Vec_t 조금도.

VEC_T는 종속 이름이 아니며 컴파일러는 템플릿을 인스턴스화하지 않고는 무엇인지 알아야합니다 (이 경우 기본 클래스). 그것은 실제로 다르지 않습니다.

template <class T>
class X
{
    std::string s;
}

여기에서도 컴파일러는 x가 인스턴스화되지 않더라도 std :: string에 대해 알아야합니다. 이름은 템플릿 인수 t에 의존하지 않기 때문에 (컴파일러가 가정 할 수있는 한).

대체로, 템플릿베이스 클래스의 typedefs는 파생 클래스에서 사용하기에는 다소 쓸모없는 것 같습니다. 그러나 typedef는 사용자에게 유용합니다.

이 개념은 우리가 사용하는 방식과 관련 될 수 있습니다 std::vector<T>. 예를 들어, 우리가있는 경우 std::vector<int> Foo. 이제 우리는 회원 유형을 사용하기로 결정했습니다. iterator. 이 시나리오에서 우리는 명시 적으로 언급합니다

std::vector<int>::iterator foo_iterator;

마찬가지로 귀하의 경우 공개 회원 유형을 사용하기 위해 Vec_ttemplate <typename T> class A, 당신은 그것을 명시 적으로 선언해야합니다

A<T>::Vec_t v;
OR
A<int>::Vec_t int_type;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top