struct Type;
Type func(Type);
Live example
당신은 어떻게 존재하고 아직 유형을 사용하는 함수를 선언하지 않는 유형을 정의 할 수 있습니까?
대답은 간단합니다. 컴파일 할 코드가 실제로 존재하지 않는 유형을 사용합니다. 컴파일 할 코드가 없으므로 어떻게 실패 할 수 있습니까?
이제 코드와 관련하여 궁금한 점이 있습니까? 클래스가 템플릿 매개 변수로 자신을 부모에게 보낼 수있는 방법은 무엇입니까?
이 struct Foo : IFoo<Foo> { /* ... */ };
첫째, 컴파일이보고 :
컴파일러는 당신이 그 일을 할 때 무엇을 볼 수의 분석하자 struct Foo ...
컴파일러는 이제 Foo
의 존재를 알고, 아직 불완전한입니다 유형.
... : IFoo<Foo> ...
그것은 IFoo
이 무엇인지 알고, 그것은 Foo
이 유형 것을 알고있다 :
지금, 그는 것으로 본다. 컴파일러는 현재 해당 유형 IFoo
을 실체화 할 수 있습니다
template <class T> struct IFoo
{
virtual T addX(T foo, double val) = 0;
};
그래서 정말, 그것에서 함수의 선언, 클래스를 선언합니다. 위에서 불완전한 타입의 함수를 선언하는 것이 효과가 있다는 것을 알았습니다. 여기에서도 마찬가지입니다. 이 코드는 다음과 같으므로 해당 코드는 가능합니다. struct Foo;
template struct IFoo<Foo>; // instanciate IFoo with Foo
그래서 실제로는 마법이 없습니다.
이제 더 확실한 예를 들어 보겠습니다. 그게 뭐야?
template<typename T>
struct IFoo {
void stuff(T f) {
f.something();
}
};
struct Foo : IFoo<Foo> {
void something() {}
};
어떻게 할 수있는 불완전한 형태의 컴파일러 호출 something
?
것은 : 그렇지 않습니다. 을 사용하면 Foo
이 완료됩니다. 이것은 템플릿 함수가 사용될 때만 인스턴스화되기 때문입니다.
템플릿과 함수 정의를 구분할 수 있습니다.
template<typename T>
struct IFoo {
void stuff(T f);
};
template<typename T>
void IFoo<T>::stuff(T f) {
f.something();
}
struct Foo : IFoo<Foo> {
void something() {}
};
위대한! 그것은 순수한 가상 함수로 당신의 예제와 똑같이 보이기 시작합니까? 다른 유효한 변환을 시도해 보겠습니다.
template<typename T>
struct IFoo {
void stuff(T f);
};
struct Foo : IFoo<Foo> {
void something() {}
};
// Later...
template<typename T>
void IFoo<T>::stuff(T f) {
f.something();
}
완료! Foo
이 완료된 후에 함수를 나중에 정의했습니다. 그리고 이것은 무슨 일이 일어나는가입니다 : 컴파일러는 IFoo<Foo>::stuff
을 사용할 때만 instanciate합니다. 그리고 사용 된 지점은 Foo
입니다. 그곳에는 마법도 없습니다.
왜 다음 IFoo
내부 T
멤버 변수를 선언 할 수 없습니다?
간단하고, 같은 이유로이 코드는 컴파일되지 않습니다 이유 : 그것은 불완전한 유형의 변수를 선언 이해가되지 않습니다
struct Bar;
Bar myBar;
.
'memberVar'는'Foo' (간접적으로) 자신의 다른 인스턴스를 보유하게 만듭니다. 본질적으로 그것은'sizeof (Foo) == 2 * sizeof (Foo)'를 만들 것이다. 물론 작동하지 않습니다.:-) –
좋은 답변을 해주셔서 감사합니다. 이제 나에게 분명하다. – jaba