これが私の問題を再現するコードサンプルです:
_template <typename myType>
class Base {
public:
Base() {}
virtual ~Base() {}
protected:
int myOption;
virtual void set() = 0;
};
template <typename InterfaceType>
class ChildClass : public Base < std::vector<InterfaceType> >
{
public:
ChildClass() {}
virtual ~ChildClass() {}
protected:
virtual void set();
};
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
myOption = 10;
}
_
main()
での使用法:
_ChildClass<int> myObject;
_
次のエラーが表示されます(ubuntuではgcc 4.4.3)。
「myOption」はこのスコープで宣言されていません
私のChildClassに新しいテンプレートパラメータがない場合、これは正常に機能します。
_class ChildClass : public Base < std::vector<SomeConcreteType> >
_
私のsetメソッドが次のようになっている場合は、なんとか解決しました:
_Base<std::vector<InterfaceType> >::myOption = 10;
_
正常に動作します。それでも、なぜすべてのテンプレートパラメータを指定する必要があるのかはわかりません。
myOption
は依存名ではありません。つまり、テンプレートの引数に明示的に依存しないため、コンパイラは早期に検索しようとします。依存名にする必要があります。
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
this->myOption = 10;
}
現在は、this
のタイプ、つまりテンプレート引数に依存しています。したがって、コンパイラーはインスタンス化時にそれをバインドします。
これは Two-phase name lookup と呼ばれます。
クラステンプレートまたはクラステンプレートのメンバーの定義で、クラステンプレートの基本クラスがテンプレートパラメーターに依存している場合、基本クラスのスコープは検査されませんクラステンプレートまたはメンバーの定義の時点での非修飾名ルックアップ中、またはクラステンプレートまたはメンバーのインスタンス化中。
次のコードが機能するはずです。
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
Base<std::vector<InterfaceType> >::myOption = 10;
}