メソッドが純粋な仮想であり、テンプレート化された型 (外側の型から注入された) のパラメーターを取り、そのテンプレート化された型がローカル型 (関数本体で定義されている) である例を考えてみましょう。このシナリオでは、g++ でコンパイル時エラーが発生します。確かに、これは非常にまれなケースですが、実際のコードに由来しています。コンパイル可能で再現可能な例を次に示します。
#include <cstdio>
template<typename T>
struct Outer
{
struct InnerBase
{
virtual void foo(T const&) = 0;
virtual void bar(T const&) { };
};
struct InnerDerived : public InnerBase
{
void foo(T const&) override { std::printf("virtual call foo() worked\n"); }
void bar(T const&) override { std::printf("virtual call bar() worked\n"); }
};
InnerBase* inner;
Outer() : inner(new InnerDerived()) { }
};
struct NonLocalStruct { };
int main()
{
struct LocalStruct { };
Outer<NonLocalStruct> a;
Outer<LocalStruct> b;
a.inner->foo(NonLocalStruct()); // fine
a.inner->bar(NonLocalStruct()); // fine
b.inner->foo(LocalStruct()); // causes error
b.inner->bar(LocalStruct()); // fine
return 0;
}
これがコンパイルエラーを引き起こす理由を誰かが説明できますか? 非ローカル型では機能するのにローカル型では機能しないのはなぜですか? 非純粋仮想メソッドが機能するのに、純粋仮想メソッドが機能しないのはなぜですか?
-std=c++11 を指定して g++ 4.8.1 を使用しています (VS2010 でもこの例を試してみましたが、コンパイルしてエラーなく実行されます)。
g++ からの正確なエラーは次のとおりです。
test.cpp:8:16: エラー: 'void Outer::InnerBase::foo(const T&) [with T = main()::LocalStruct]'、ローカル型 'const main()::LocalStruct' を使用して宣言、使用されていますが、定義されていません [-fpermissive]