【问题标题】:Use of undeclared identifier in C++ with templates and inheritance [duplicate]在带有模板和继承的 C++ 中使用未声明的标识符 [重复]
【发布时间】:2012-05-30 22:13:44
【问题描述】:

以下代码无法编译 - 使用了未声明的标识符。我使用 GCC 和 XCode 进行编译。

所有内容都在一个头文件中。

include "MyArray.h"

template <typename T>
class MyBase {
public:
  MyBase();
  virtual ~MyBase();
  void addStuff(T* someStuff);
protected:
  MyArray<T*> stuff;
};

template <typename T>
MyBase<T>::MyBase() {}
template <typename T>
MyBase<T>::~MyBase() {}

template <typename T>
void MyBase<T>::addStuff(T* someStuff) {
  stuff.add(someStuff);
}

// ---------------------

template <typename T>
class MyDerived : public MyBase<T> {
public:
  MyDerived();
  virtual ~MyDerived();
  virtual void doSomething();
};

template <typename T>
MyDerived<T>::MyDerived() {}
template <typename T>
MyDerived<T>::~MyDerived() {}

template <typename T>
void MyDerived<T>::doSomething() {
  T* thingy = new T();
  addStuff(thingy); //here's the compile error. addStuff is not declared.
}

有人解释一下吗? 提前致谢!

【问题讨论】:

  • @jua 你肯定需要查找有关不合格名称的受诅依赖的基本查找规则。你说的是不正确的。符合标准的编译器将需要它。

标签: c++ templates inheritance


【解决方案1】:

试试

this->addStuff(thingy);

【讨论】:

  • @juanchopanza:实际上,这是正确的,因为编译器不知道它是依赖的。
  • @moo 它肯定依赖的并且在实例化时被查找。
  • @JohannesSchaub-litb 谢谢,我将不得不做一些阅读。我设法说服自己这是正确的这是错误的。
  • 这对我来说太奇怪了!我也只是有点。您是否有一些文档/文章的链接来解释为什么会这样?
  • @GiovanniBotta 实际上我找到了一个更好的副本,有更好的答案。请参阅问题标题下的链接。
【解决方案2】:

这是由于模板继承。在这种情况下,您应该手动指定使用基本方法:

template <typename T>
MyDerived<T>::doSomething() {
  using MyBase<T>::addStuff;
  T* thingy = new T();
  addStuff(thingy); 
}

或者通过这个指针来做:

template <typename T>
MyDerived<T>::doSomething() {
  T* thingy = new T();
  this->addStuff(thingy); 
}

【讨论】:

    【解决方案3】:

    有几个问题:

    1. 类定义后缺少分号。
    2. 缺少doSomething 方法声明/定义的类型。
    3. addStuff 方法的定义缺少类型。

    修复it seems to work之后。

    编辑:您已经修复了语法错误,但它仍然无法正常工作。正如其他人所建议的那样,您的编译器可能会要求您使用 this-&gt; 前缀调用 addStuff 方法:

    this->addStuff(thingy);
    

    【讨论】:

    • 我认为,这不应该作为标准。 this-&gt; 部分是这里的要求。
    • @Nawaz:MSVC2010 也可以。您能否从标准中发布引文,为什么它不应该起作用?
    • @Nawaz:不,在这种情况下,这不是必需的。有关详细信息,请参阅我对您的答案的评论。
    • @JurajBlaho:如果您想了解有关两阶段名称查找的更多信息,请参阅:The Dreaded Two-Phase Name Lookup
    • @mike 你错了。 this-> 前缀是必需的。该名称是依赖的,不足以在依赖的基类中查找它。 gcc 在他们的最新版本中修复了这个错误。
    【解决方案4】:

    使用此指针调用 addStuff 方法,即

    this->addStuff(thingy);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      相关资源
      最近更新 更多