“未在此范围内声明”模板和继承错误

时间:2011-08-16 09:33:01

标签: c++ templates inheritance g++ compiler-errors

以下是重现我的问题的代码示例:

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;

工作正常。尽管不确定为什么我需要指定所有模板参数。

2 个答案:

答案 0 :(得分:43)

myOption不是依赖名称,即它不依赖于模板参数,因此编译器会尝试提前查找它。你必须使它成为一个从属名称:

template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
     this->myOption = 10;
}

现在它取决于this的类型,因此取决于模板参数。因此,编译器将在实例化时绑定它。

这称为Two-phase name lookup

答案 1 :(得分:13)

C ++ 03 14.6.2从属名称

  

在类模板的定义或类模板的成员中,   如果类模板的基类依赖于模板参数,   在非限定名称期间,基类范围为 未检查   在类模板的定义点或者查找   成员或在类模板或成员的实例化期间。

以下代码应该有效。

template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
   Base<std::vector<InterfaceType> >::myOption = 10;
}