初始化对struct

时间:2019-01-16 17:24:26

标签: c++11 reference eigen3

我有一个表示3D位置的结构。有时方便访问各个组件,有时方便将所有组件作为向量(物理向量不是std :: vector)来访问,为此我正在使用本征线性代数库。由于只有三个元素(x,y,z)并且将永远只有三个元素,所以具有三个引用本征矩阵元素的double&的结构有什么问题吗?即:

using ColumnVector3 = Eigen::Matrix<double, 3, 1>;

struct EnuPosition
{
  EnuPosition(): pos(ColumnVector3::Zero()), east(pos[0]), north(pos[1]), up(pos[2]) {}

  EnuPosition(double east, double north, double up): pos((ColumnVector3() << east, north, up).finished()),
    east(pos[0]), north(pos[1]), up(pos[2]) {}

  EnuPosition(const ColumnVector3& position): pos(position), east(pos[0]), north(pos[1]), up(pos[2]) {}

  EnuPosition(const EnuPosition& enu):pos(enu.pos), east(pos[0]), north(pos[1]), up(pos[2]) {}

  EnuPosition& operator=(const EnuPosition& enu)
  {
    this->pos = enu.pos;
    return *this;  
  }

  ColumnVector3 pos;
  double& east;
  double& north;
  double& up;
};

在我能想到的用例中,使用-Wall -Wextra -pedantic在g ++ 5.5上没有任何警告,它可以很好地编译:

int main ()
{
  EnuPosition enu{12.5, 34.2, 99.2};
  std::cout << "east: " << enu.east
        << " north: " << enu.north 
        << " up: " << enu.up
        << std::endl;

  ColumnVector3 x;
    x << 2.0,3.0,4.0;

  enu.pos = x;

  std::cout << "east: " << enu.east
        << " north: " << enu.north 
        << " up: " << enu.up
        << std::endl;

  Eigen::MatrixXd y;
  y.resize(3,1);

  y << 7.6,8.7,9.8;

  enu.pos = y;

  std::cout << "east: " << enu.east
      << " north: " << enu.north 
      << " up: " << enu.up
      << std::endl;

  Eigen::Matrix<double,3,3> R;

  enu.east = 1;
  enu.north = 1;
  enu.up = 1;

  R << 1,2,3,4,5,6,7,8,9;

  enu.pos = (R * enu.pos).eval();

  std::cout << "east: " << enu.east
    << " north: " << enu.north 
    << " up: " << enu.up
    << std::endl;

  EnuPosition enu2 = enu;
  std::cout << "east: " << enu2.east
    << " north: " << enu2.north 
    << " up: " << enu2.up
    << std::endl;
}

就像我说的那样,它行得通,我只是想知道它是否合法并且不依赖未定义的行为等。或者还有其他问题需要认识吗?

1 个答案:

答案 0 :(得分:1)

添加副本分配后,您的代码应该是安全的。

但是,如果您可以在代码中编写east()而不是east,那么可能会有以下更优雅的解决方案:

using ColumnVector3 = Eigen::Matrix<double, 3, 1>;

struct EnuPosition : public ColumnVector3
{
  EnuPosition(): ColumnVector3(ColumnVector3::Zero()) {}

  EnuPosition(double east, double north, double up): ColumnVector3(east, north, up) {}
  template<class X> 
  EnuPosition(const X& other): ColumnVector3(other) {}

  double&       east()        {return this->x();}
  double const& east() const  {return this->x();}
  double&       north()       {return this->y();}
  double const& north() const {return this->y();}
  double&       up()          {return this->z();}
  double const& up() const    {return this->z();}
};

如果您有意不想继承,您当然仍可以将ColumnVector3存储为成员。