문제

이 질문은 이 스레드.

다음 클래스 정의 사용 :

template <class T>
class Foo {

public:
    Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg)
    {
        /* do something for foo */
    }
    T Foo_T;        // either a TypeA or a TypeB - TBD
    foo_arg_t _foo_arg;
};

template <class T>
class Bar : public Foo<T> {
public:
    Bar (const foo_arg_t bar_arg, const a_arg_t a_arg)
    : Foo<T>(bar_arg)   // base-class initializer
    {

        Foo<T>::Foo_T = T(a_arg);
    }

    Bar (const foo_arg_t bar_arg, const b_arg_t b_arg)
    : Foo<T>(bar_arg)
    {
        Foo<T>::Foo_T = T(b_arg);
    }

    void BarFunc ();

};

template <class T>
void Bar<T>::BarFunc () {
    std::cout << _foo_arg << std::endl;   // This doesn't work - compiler error is: error: ‘_foo_arg’ was not declared in this scope
    std::cout << Bar<T>::_foo_arg << std::endl;   // This works!
}

템플릿 클래스의 기본 클래스 멤버에 액세스 할 때는 템플릿 스타일 구문을 사용하여 항상 멤버를 명시 적으로 자격을 갖추어야하는 것 같습니다. Bar<T>::_foo_arg. 이것을 피할 수있는 방법이 있습니까? 코드를 단순화하기 위해 '사용'명령문/지시문이 템플릿 클래스 메소드에서 작동 할 수 있습니까?

편집하다:

범위 문제는이> 구문으로 변수를 자격으로하여 해결됩니다.

도움이 되었습니까?

해결책

당신이 사용할 수있는 this-> 수업 구성원을 언급하고 있음을 분명히하기 위해 :

void Bar<T>::BarFunc () {
    std::cout << this->_foo_arg << std::endl;
}

또는 사용할 수도 있습니다. "using"방법에서 :

void Bar<T>::BarFunc () {
    using Bar<T>::_foo_arg;             // Might not work in g++, IIRC
    std::cout << _foo_arg << std::endl;
}

이렇게하면 컴파일러가 멤버 이름이 템플릿 매개 변수에 의존하여 올바른 위치에서 해당 이름의 정의를 검색 할 수 있음을 분명히합니다. 자세한 내용은 참조하십시오 C ++ FAQ 라이트 의이 항목.

다른 팁

여기서 기본 클래스는 비 의존적 기본 클래스가 아닙니다 (템플릿 인수를 모르고 결정할 수있는 완전한 유형을 가진 사람). _foo_arg 비 의존적 이름입니다. Standard C ++에 따르면 의존적 인 이름은 종속 기본 클래스에서 찾지 못한다고 말합니다.

코드를 수정하려면 이름을 만들기에 충분합니다. _foo_arg 종속 이름은 인스턴스화 시점에만 의존적 인 이름을 찾을 수 있기 때문에, 그 당시에는 탐색 해야하는 정확한 기본 전문화가 알려질 것입니다. 예를 들어:

// solution#1
std::cout << this->_foo_arg << std::endl;

대안은 자격을 갖춘 이름을 사용하여 종속성을 소개하는 것으로 구성됩니다.

// solution#2
std::cout << Foo<T>::_foo_arg << std::endl;

자격이없는 비 의존적 이름이 가상 함수 호출을 형성하는 데 사용되면 자격이 가상 호출 메커니즘과 프로그램의 의미를 억제하기 때문에이 솔루션을 사용해야합니다.

파생 클래스의 부양 기본 클래스에서 이름을 한 번 가져올 수 있습니다. using:

// solution#3
template <class T>
class Bar : public Foo<T> {
public:
    ...
    void BarFunc ();
private:
    using Foo<T>::_foo_arg;
};

template <class T>
void Bar<T>::BarFunc () {
    std::cout << _foo_arg << std::endl;   // works
}

Visual C ++ 2008에서 잘 작동하는 것으로 보입니다. 언급 한 유형에 대해 더미 정의를 추가했지만 소스는 없었습니다. 나머지는 정확히 당신이 넣은 것과 같습니다. 그런 다음 강제의 주요 기능 BarFunc 인스턴스화되고 부름.

#include <iostream>

class streamable {};
std::ostream &operator<<(std::ostream &os, streamable &s) { return os; }

class foo_arg_t : public streamable {};
class a_arg_t : public streamable {};
class b_arg_t : public streamable  {};

template <class T>
class Foo {

public:
    Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg)
    {
        /* do something for foo */
    }
    T Foo_T;        // either a TypeA or a TypeB - TBD
    foo_arg_t _foo_arg;
};

template <class T>
class Bar : public Foo<T> {
public:
    Bar (const foo_arg_t bar_arg, const a_arg_t a_arg)
    : Foo<T>(bar_arg)   // base-class initializer
    {

        Foo<T>::Foo_T = T(a_arg);
    }

    Bar (const foo_arg_t bar_arg, const b_arg_t b_arg)
    : Foo<T>(bar_arg)
    {
        Foo<T>::Foo_T = T(b_arg);
    }

    void BarFunc ();

};

template <class T>
void Bar<T>::BarFunc () {
    std::cout << _foo_arg << std::endl; 
    std::cout << Bar<T>::_foo_arg << std::endl;   
}

int main()
{
    Bar<a_arg_t> *b = new Bar<a_arg_t>(foo_arg_t(), a_arg_t());
    b->BarFunc();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top