【问题标题】:Cannot find a namespace despite it being RIGHT THERE找不到名称空间,尽管它就在那儿
【发布时间】:2012-04-28 10:28:02
【问题描述】:

我在一个头文件中定义了一个名称空间并在另一个头文件中使用,但找不到它。具体来说,在“players/Players.hpp”中定义并在名为“players/Ownable.hpp”的文件中使用的名为“players”的命名空间无法在名为“combat/Targetable.hpp”的文件中找到

错误是

...\source\combat\Targetable.hpp(7): 'players' : is not a class or namespace name
...\source\combat\Targetable.hpp(7): 'Ownable' : base class undefined

显然这是一些我不明白的语法。我花了一些时间简化代码,所以它看起来很傻,但请耐心等待。

// source/players/Players.hpp:
#ifndef PLAYERS_HPP
#define PLAYERS_HPP

#include "../Headers.hpp"

namespace players {
  class Player{

// this class compiles fine.
// There used to be a "Players.cpp" but it's been simplified away

    public:
      int getID(){ return 0; }
      int getTeam(){ return 0; }
      string getName(){ return ""; }
      Vec3 getColor(){ return Vec3(0.0,0.0,0.0); }
  };
}
#endif

还有players/Ownable.hpp,它和Player.hpp在同一个文件夹里,编译也很好:

// source/players/Ownable.hpp:
#ifndef OWNABLE_HPP
#define OWNABLE_HPP

#include "Players.hpp"

namespace players {
  class Ownable;
  typedef boost::shared_ptr<Ownable> OwnablePTR;
  typedef boost::weak_ptr<Ownable> OwnableWPTR;

  class Ownable {
    public:
      Ownable(){}
      Ownable(int playerID) : playerID(playerID){}
      bool isAlliedWith(OwnablePTR other){ return false; }

    private:
      int playerID;
  };
}

#endif

这里是乐趣的开始。我在“source/combat/Targetable.hpp”中有一个文件,该文件与其他两个文件位于不同的目录中。但是,文件本身似乎包含罚款:

// source/combat/Targetable.hpp:
#ifndef TARGETABLE_HPP
#define TARGETABLE_HPP

#include "../players/Ownable.hpp"

namespace combat{
  class Targetable : public players::Ownable { // ERROR
    public:
      Targetable(int playerID){}
      //Targetable(players::Player player);

      virtual Vec2 getPosition(){
        return Vec2();
      }
      virtual Vec2 getVelocity(){
        return Vec2();
      }
  };
}

#endif

我真的希望这是我缺少的一些愚蠢的语法。我什至尝试过

using players::Ownable;

但是 A) 污染了包含这个文件的文件,并且 B) 没有解决任何问题。有什么帮助吗?

编辑:GManNickG 明白了,它是 Headers.hpp 文件中的循环包含。谢谢!

【问题讨论】:

  • Headers.hpp 包括什么?我闻到一个圆形的包括。
  • 标头包括 Camera.hpp 等,其中确实包括战斗/Targetable.hpp。删除该包含似乎可以解决问题。但是,我认为包含警卫应该处理这个问题。
  • 我们能够帮助您的唯一方法是您发布一个完整示例,这样我们就可以尝试编译它并自己查看错误。
  • 我 99% 都愿意成为你没有关闭标题中某处的命名空间
  • 为什么不接受答案而不是编辑问题?

标签: c++ inheritance namespaces syntax-error


【解决方案1】:

你有一个循环包含。

首先考虑包含守卫的目的:

// a.hpp
#ifndef A_HPP
#define A_HPP

// stuff

#endif

 

// b.hpp
#ifndef B_HPP
#define B_HPP

#include "a.hpp"

// stuff

#endif

 

// c.hpp
#ifndef C_HPP
#define C_HPP

#include "a.hpp"
#include "b.hpp"

// stuff

#endif

 

// x.cpp
#include "c.hpp"

包含c.hpp 最终会包含a.hpp 两次。第一次,守卫没有定义,一切正常,第二次守卫阻止重新定义。这就是我们想要的。

但是,当您有循环时,这不起作用。 (它会阻止它,这很好,但它做得“太好了”,因为防护是在测试后立即定义的,这意味着标题的内容实际上还没有被处理)。请考虑一下:

// a.hpp
#ifndef A_HPP
#define A_HPP

#include "c.hpp"

// stuff

#endif

 

// b.hpp
#ifndef B_HPP
#define B_HPP

#include "a.hpp"

// stuff

#endif

 

// c.hpp
#ifndef C_HPP
#define C_HPP

#include "b.hpp"

// stuff

#endif

 

// x.cpp
#include "c.hpp"

这与您所拥有的相似。 x.cpp 包括c.hpp,这是它第一次被包括在内,因此它定义了C_HPP。那么c.hpp包括b.hpp,其中包括a.hpp。然后a.hpp 包含c.hpp 并且发现C_HPP 已经被定义,所以包含什么都不做。

假设a.hpp 仍然可以编译(也就是说,c.hpp 实际上并不需要),然后a.hpp 完成,然后b.hpp 完成,然后c.hpp 在返回@之前最终实际定义了它的内容987654345@.

解决方案是尽量减少包含的标头数量。使用前向声明,最重要的是:不要使用“包含所有内容”标题!这些是可怕的。我怀疑这就是Headers.hpp

【讨论】:

    【解决方案2】:

    class Targetable : public ::players::Ownable { . . .怎么样?

    注意:: 之前的全局命名空间限定players

    【讨论】:

    • 我试过了,不行:“'玩家':'::'左边的符号必须是类型”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 2014-04-24
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 1970-01-01
    相关资源
    最近更新 更多