C++ “访问”;“公众”;类内部定义的结构

C++ “访问”;“公众”;类内部定义的结构,c++,C++,我试图创建一个类,其私有成员必须访问同一类中使用公共访问权限定义的结构。我正在使用VS代码来编写代码。当我试图编写一个私有成员函数时,它说没有定义结构标识符 class Planner { private: typedef std::pair<int, int> location; std::vector<location> obstacles; Pose next_state(const Pose& current_state, co

我试图创建一个类,其私有成员必须访问同一类中使用公共访问权限定义的结构。我正在使用VS代码来编写代码。当我试图编写一个私有成员函数时,它说没有定义结构标识符

class Planner
{
  private:
    typedef std::pair<int, int> location;
    std::vector<location> obstacles;
    Pose next_state(const Pose& current_state, const Command& command);

  public:
    Planner(/* args */);
    virtual ~Planner();

    /* data */
    struct Command
    {
        unsigned char direction;
        unsigned char steering;
    };

    struct Pose
    {
        int x;
        int y;
        int theta;
    };

    struct Node
    {
        Pose pose;
        int f;
        int g;
        int h;
    };
};

类计划器
{
私人:
typedef std::对位置;
病媒障碍;
姿势下一个_状态(常量姿势和当前_状态、常量命令和命令);
公众:
规划师(/*args*/);
虚拟规划器();
/*资料*/
结构命令
{
无符号字符方向;
无符号字符转向;
};
结构姿势
{
int x;
int-y;
内θ;
};
结构体类型
{
摆姿势;
int f;
int g;
int-h;
};
};

这里,它表示“标识符”姿势“未定义”。我想了解这里发生了什么。

文件是按顺序解析的。在定义姿势之前,您正在引用该姿势。可以使用成员函数和变量执行此操作,但这些是例外,而不是规则

在您的案例中,解决此问题的一个简单方法是将私有部分移到末尾

这里,它表示“标识符”姿势“未定义”。我想知道这里发生了什么

这是因为在编译器可以在
private
部分看到它们之前,您引入了
Pose
Command
类型引用:

private:
    // ...
    Pose next_state(const Pose& current_state, const Command& command);
                       // ^^^^                       ^^^^^^^
编译器需要在使用标识符之前查看它们


解决这个问题的方法是,您需要在
Planner
类中正确地排序前向声明:

class Planner {
  // <region> The following stuff in the public access section,
  // otherwise an error about "redeclared with different access" will occur.
  public:
    struct Pose;
    struct Command;
  // </region> 

  private:
    typedef std::pair<int, int> location;
    std::vector<location> obstacles;
    Pose next_state(const Pose& current_state, const Command& command);

  public:
    Planner(/* args */);
    virtual ~Planner();

    /* data */
    struct Command {
        unsigned char direction;
        unsigned char steering;
    };

    struct Pose {
        int x;
        int y;
        int theta;
    };

    struct Node {
        Pose pose;
        int f;
        int g;
        int h;
    };
};
类计划器{
//公共访问部分的以下内容,
//否则,将出现关于“使用不同访问权限重新声明”的错误。
公众:
结构姿势;
结构命令;
//  
私人:
typedef std::对位置;
病媒障碍;
姿势下一个_状态(常量姿势和当前_状态、常量命令和命令);
公众:
规划师(/*args*/);
虚拟规划器();
/*资料*/
结构命令{
无符号字符方向;
无符号字符转向;
};
结构姿势{
int x;
int-y;
内θ;
};
结构节点{
摆姿势;
int f;
int g;
int-h;
};
};

另一种方法是重新排列中提到的
public
private
部分1



1) 注意这些可以在一个类声明中多次提供。

还要考虑:您可以稍微重新安排代码,而无需添加行

class Planner
{
private:
   typedef std::pair<int, int> location;
   std::vector<location> obstacles;
   // "next_state" private method moved below

public:
   Planner(/* args */){};
   virtual ~Planner(){};

   /* data */
   struct Command
   {
      unsigned char direction;
      unsigned char steering;
   };

   struct Pose
   {
      int x;
      int y;
      int theta;
   };

   struct Node
   {
      Pose pose;
      int f;
      int g;
      int h;
   };

private:
   Pose next_state(const Pose& current_state, const Command& command);

};
类计划器
{
私人:
typedef std::对位置;
病媒障碍;
//“下一个州”私有方法移到下面
公众:
计划者(/*args*/){};
虚拟~Planner(){};
/*资料*/
结构命令
{
无符号字符方向;
无符号字符转向;
};
结构姿势
{
int x;
int-y;
内θ;
};
结构体类型
{
摆姿势;
int f;
int g;
int-h;
};
私人:
姿势下一个_状态(常量姿势和当前_状态、常量命令和命令);
};
您可能有多个私人部门


此外,您可以考虑在类声明结束时将所有私有属性一起移动。

StEnOuto:类内的函数定义可以支持排序,并使用类中稍后声明的成员。@ USER881301,我猜我不理解您的注释。为什么这个答案是错误的?我自己对此感到困惑。太简单了?前进宣言在意识形态上更正确?没有线索。我只想指出的是,有一个例外,一切都是按顺序处理的,因为大多数时候你说的是正确的。这个答案的第一个版本是错误的(-1)。目前的版本一般,但我们实际上不需要它,因为我们现在有了好的答案。@anatolyg:其他答案都没有试图解释什么是错的。当然,另一种方法是重新安排而不是提前声明。好的选择。