불완전한 유형의 잘못된 사용
내 프로젝트의 하위 클래스에서 typedef를 사용하려고하는데 아래 예제에서 내 문제를 격리했습니다.
내가 어디로 잘못 가고 있는지 아는 사람이 있습니까?
template<typename Subclass>
class A {
public:
//Why doesn't it like this?
void action(typename Subclass::mytype var) {
(static_cast<Subclass*>(this))->do_action(var);
}
};
class B : public A<B> {
public:
typedef int mytype;
B() {}
void do_action(mytype var) {
// Do stuff
}
};
int main(int argc, char** argv) {
B myInstance;
return 0;
}
이것은 내가 얻는 출력입니다.
sean@SEAN-PC:~/Documents/LucadeStudios/experiments$ g++ -o test test.cpp
test.cpp: In instantiation of ‘A<B>’:
test.cpp:10: instantiated from here
test.cpp:5: error: invalid use of incomplete type ‘class B’
test.cpp:10: error: forward declaration of ‘class B’
그 이유는 클래스 템플릿을 인스턴스화 할 때 멤버 함수의 모든 선언 (정의가 아님)도 인스턴스화되기 때문입니다. 클래스 템플릿은 전문화의 전체 정의가 필요할 때 정확하게 인스턴스화됩니다. 예를 들어 귀하의 경우와 같이 기본 클래스로 사용되는 경우입니다.
무슨 일 것은 그래서는 A<B>
에서 인스턴스화
class B : public A<B>
이 시점에서 B
아직 완전한 유형이 아닙니다 (클래스 정의의 닫는 중괄호 뒤에 있음). 그러나 A<B>::action
의 선언은 B
범위 내에서 크롤링되기 때문에 완전 해야 합니다.
Subclass::mytype
여러분이해야 할 일은 인스턴스화를 B
완료 되는 어느 시점까지 지연시키는 것입니다 . 이를 수행하는 한 가지 방법은의 선언을 수정하여 action
구성원 템플릿으로 만드는 것입니다.
template<typename T>
void action(T var) {
(static_cast<Subclass*>(this))->do_action(var);
}
아직 입력 안전을하는 경우 때문에 var
통과, 권리 유형이 아닌 var
에 do_action
실패합니다.
특성 클래스를 사용하여이 문제를 해결할 수 있습니다. 사용하는
각 실제 클래스에 대해 특수 특성 클래스를 설정해야합니다.
template<typename SubClass>
class SubClass_traits
{};
template<typename Subclass>
class A {
public:
void action(typename SubClass_traits<Subclass>::mytype var)
{
(static_cast<Subclass*>(this))->do_action(var);
}
};
// Definitions for B
class B; // Forward declare
template<> // Define traits for B. So other classes can use it.
class SubClass_traits<B>
{
public:
typedef int mytype;
};
// Define B
class B : public A<B>
{
// Define mytype in terms of the traits type.
typedef SubClass_traits<B>::mytype mytype;
public:
B() {}
void do_action(mytype var) {
// Do stuff
}
};
int main(int argc, char** argv)
{
B myInstance;
return 0;
}
B
에서 파생 A<B>
되므로 컴파일러가 가장 먼저하는 일은 클래스 정의 B
를 확인한 후 인스턴스화를 시도하는 것 A<B>
입니다. 이를 위해서는 B::mytype
의 매개 변수 를 알아야 합니다 action
. 그러나 컴파일러는의 실제 정의를 파악하는 중이므로 B
아직이 유형을 알지 못하며 오류가 발생합니다.
이 문제를 해결하는 한 가지 방법은 매개 변수 유형을 파생 클래스 내부가 아닌 다른 템플릿 매개 변수로 선언하는 것입니다.
template<typename Subclass, typename Param>
class A {
public:
void action(Param var) {
(static_cast<Subclass*>(this))->do_action(var);
}
};
class B : public A<B, int> { ... };
정확히 무엇을 요구했는지는 아니지만 작업을 템플릿 멤버 함수로 만들 수 있습니다.
template<typename Subclass>
class A {
public:
//Why doesn't it like this?
template<class V> void action(V var) {
(static_cast<Subclass*>(this))->do_action();
}
};
class B : public A<B> {
public:
typedef int mytype;
B() {}
void do_action(mytype var) {
// Do stuff
}
};
int main(int argc, char** argv) {
B myInstance;
return 0;
}
현재 컴파일러가 인스턴스화 할 수없는 적절한 유형을 알 수 없으므로 포인터 또는 참조를 사용해야합니다.
대신 다음을 시도하십시오.
void action(const typename Subclass::mytype &var) {
(static_cast<Subclass*>(this))->do_action();
}
ReferenceURL : https://stackoverflow.com/questions/652155/invalid-use-of-incomplete-type
'IT이야기' 카테고리의 다른 글
낮은 디스크 워터 마크 [?? %] 초과 (0) | 2021.05.01 |
---|---|
애자일 환경에서 대규모 프로젝트에 대한 견적 제공 (0) | 2021.05.01 |
객체(트리)를 재귀적으로 반복 (0) | 2021.05.01 |
'super'키워드로 제네릭 경계 지정 (0) | 2021.05.01 |
익명 유형 동적 생성 (0) | 2021.04.30 |