【问题标题】:"not declared in this scope" error with templates and inheritance [duplicate]模板和继承的“未在此范围内声明”错误[重复]
【发布时间】:2011-10-27 22:01:10
【问题描述】:

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

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 是一个从属名称,它将与 this-&gt; 一起使用

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


【解决方案1】:

myOption 不是依赖名称,即它不显式依赖模板参数,因此编译器会尝试及早查找它。您必须将其设为从属名称:

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

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

这叫Two-phase name lookup

【讨论】:

  • +1,我知道但还是错过了。 :)
  • 可能需要另一个问题,但是有没有办法避免this-&gt;myVar 引用每个基类变量?它使代码难看。
  • @JoeyDumont:我想不出来。定义一个名为 myOption() 的函数返回对 this->myOption 的引用将缩短 this(不是双关语),但 IMO 会更难看。此外,我认为this-&gt; 一点也不丑。比如说,这就是你用 C 编写它的方式。
  • 在 Visual Studio 2008 中没有这个也可以工作,只需 myOption = 10;没问题。
  • @qub1n:不行。如果编译此代码,则不是 Visual Studio 2008。确实指定什么是正确的 C++ 的权威是 ISO WG21,它说这个程序是无效的(请参阅其他答案以获取引号)。
【解决方案2】:

C++03 14.6.2 从属名称

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

以下代码应该可以工作。

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

【讨论】:

  • (反问)很好,但是为什么
  • 感谢您的提醒。我更新了我的答案。
  • @Eric:更好;)您的答案和 ybungalobill 的结合将是完美的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-05
  • 2012-04-20
  • 1970-01-01
相关资源
最近更新 更多