次の最小限の例はコンパイルされません。
template<class T>
class Base1 {};
template<class Impl>
class Base2 : public Base1<typename Impl::Inner> {}; // line 5
struct C : public Base2<C> // line 7
{
class Inner;
};
int main()
{
C c;
(void)c;
return 0;
}
エラー:
> g++ -std=c++11 -Wall incomplete.cpp -o incomplete
incomplete.cpp: In instantiation of ‘class Base2<C>’:
incomplete.cpp:7:19: required from here
incomplete.cpp:5:7: error: invalid use of incomplete type ‘struct C’
incomplete.cpp:7:8: error: forward declaration of ‘struct C’
ただし、Base2 のコードを次のように置き換えると、次のようになります。
template<class Impl>
class Base2
{
struct BaseInner : public Base1<typename Impl::Inner> {};
};
なぜ(正確に)エラーが発生しないのですか?最初のコード例のエラーを取り除くことはできますか?
注: 次のコードはもちろん機能しますが、C のようなクラスを作成するたびに 2 回継承する必要があるという欠点があります。
template<class Impl>
class Base2
{
struct BaseInner : public Base1<typename Impl::Inner> {};
};
struct _C : public Base2<_C> // line 7
{
class Inner {};
};
struct C : public _C, _C::Inner
{
};