以下は、私が抱えている問題を再現するためのコードです。Base
class は、仮想関数 を持つテンプレート クラスfoo
です。foo
渡された引数を追加するデフォルトの実装があります。
SimpleDerived
から派生しBase
、 で特殊化しstd::string
ます。SimpleDerived
仮想Base<T>::foo()
関数をオーバーロードします。このクラスは正常にコンパイルfoo
され、 で呼び出されたときに期待どおりに出力されmain
ます。
#include <iostream>
template<class T>
struct Base
{
virtual void foo(T val)
{
T local = val + val; // THE OFFENDING LINE OF CODE
std::cout << "Base" << std::endl;
}
};
struct SimpleDerived : public Base<std::string>
{
virtual void foo(std::string val)
{
std::cout << "SimpleDerived" << std::endl;
}
};
struct SimpleObject
{
int value;
};
struct ComplexDerived : public Base<SimpleObject>
{
virtual void foo(SimpleObject val)
{
std::cout << "ComplexDerived" << std::endl;
}
};
int main(void)
{
Base<int> base;
base.foo(2);
SimpleDerived simpleDerived;
simpleDerived.foo("hello world");
SimpleObject object;
ComplexDerived complexDerived;
complexDerived.foo(object);
return 0;
}
ComplexDerived
から派生しBase
、カスタム struct で特殊化しSimpleObject
ます。ComplexDerived
オーバーロードfoo
も。しかし、これが問題の根源です。これをコンパイルしようとすると、次のようになります。
quicktest.cpp: In member function ‘void Base<T>::foo(T) [with T = SimpleObject]’:
quicktest.cpp:47:1: instantiated from here
quicktest.cpp:8:19: error: no match for ‘operator+’ in ‘val + val’
明らかに、 には演算子「+」はありませんSimpleObject
。Base<SimpleObject>::foo
しかし、ここに私の混乱があります..これがComplexDerived
継承元であるため、コンパイラは実装を求められています。ただし、使用したり呼び出したりすることはありませんBase<SimpleObject>::foo
。では、コンパイラはこの基底クラス関数を生成しようとするべきでしょうか?