기본 클래스 멤버 데이터에 대한 파생 템플릿 클래스 액세스
이 질문은 이 스레드 에서 요청한 질문의 지원입니다 .
다음 클래스 정의 사용 :
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
. 이것을 피할 수있는 방법이 있습니까? 코드를 단순화하기 위해 템플릿 클래스 메서드에서 'using'문 / 지시문을 사용할 수 있습니까?
편집하다:
범위 문제는 this-> 구문으로 변수를 한정하면 해결됩니다.
를 사용 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 Lite의이 항목을 참조하십시오 .
여기서 기본 클래스는 비 종속 기본 클래스 (템플릿 인수를 알지 못해도 확인할 수있는 완전한 유형을 가진 클래스를 의미 함) _foo_arg
가 아니며 비 종속적 인 이름입니다. 표준 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();
}
참조 URL : https://stackoverflow.com/questions/1120833/derived-template-class-access-to-base-class-member-data
'developer tip' 카테고리의 다른 글
Xcode 10은 com.apple.commcenter.coretelephony.xpc를 깨는 것 같습니다 (0) | 2020.12.25 |
---|---|
jQuery에서 두 태그 사이의 모든 콘텐츠를 선택하는 방법 (0) | 2020.12.25 |
이것은 무엇을 의미 하는가? (0) | 2020.12.25 |
Why does Map.of not allow null keys and values? (0) | 2020.12.24 |
What is the fastest way to parse large XML docs in Python? (0) | 2020.12.24 |