为什么不排序工作

时间:2017-04-26 14:49:36

标签: c++ compiler-errors

在读入并处理某些信息后,我编写了以下程序来按时间排序struct的向量,但它不起作用并给我错误信息:

`no matching function for call to ‘swap(collisionOfCars&, collisionOfCars&)’`,`error: no type named ‘type’ in ‘struct
std::enable_if<false, void>’` and `error: use of deleted function
‘collisionOfCars& collisionOfCars::operator=(collisionOfCars&&)’
*(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));`

我的猜测是排序功能有一些问题,但我不知道如何解决它。 这是我的代码;

  class Car{
 public:
    string ID;
    double xPos, yPos, xVel, yVel;
    bool collided;
    Car(){

    }
    Car(string ID, double xPos, double yPos, double xVel, double yVel, bool collided){
      this->ID = ID;
      this->xPos = xPos;
      this->yPos = yPos;
      this->xVel = xVel;
      this->yVel = yVel;
      this->collided = collided;
    }
};
struct collisionOfCars{
 public:
  Car &firstCar;
  Car &secondCar;
  double time;
};
bool tupleCompare(collisionOfCars first, collisionOfCars second) {
  return first.time < second.time;
}
collisionOfCars willCollide(Car &car1, Car &car2) {
   double posDifX = car1.xPos - car2.xPos;
   double posDifY = car1.yPos - car2.yPos;
   double velDifX = car1.xVel - car2.xVel;
   double velDifY = car1.yVel - car2.yVel;

   double a = velDifX*velDifX + velDifY*velDifY;
   double b = posDifX*velDifX+posDifY*velDifY;
   double c = posDifX*posDifX + posDifY*posDifY - 100;
   double possibleSol = b*b - a*c;     // b^2-4ac

  double sol1, sol2;
  if ((a == 0) || possibleSol < 0) {     // check for a = 0 or b^2-4ac < 0
    return collisionOfCars{car1, car2, -1};
  } else if (possibleSol == 0) {
    sol1 = -b/(2*a);
    if(sol1 >= 0){
      return collisionOfCars{car1, car2, sol1};
    }
  } else {
    sol1 = (-b + sqrt(possibleSol))/(a);
    sol2 = (-b - sqrt(possibleSol))/(a);
    if (sol1 <= sol2 && sol1 >= 0) {
      return collisionOfCars{car1, car2, sol1};
    } else if (sol2 <= sol1 && sol2 >= 0) {
      return collisionOfCars{car1, car2, sol2};
    } else {
      return collisionOfCars{car1, car2, -1};
    }
  }
}
int main() {
  vector< Car > collection;     // All info of cars
  vector< collisionOfCars > collision;      // all possible collision
  string ID;
  double xPos, yPos, xVel, yVel;
  while (cin >> ID >> xPos >> yPos >> xVel >> yVel) {
    collection.push_back(Car(ID, xPos, yPos, xVel, yVel, false));
  }
  for (int i = 0; i < collection.size(); i++) {
    for (int j = i+1; j < collection.size(); j++) {
      collisionOfCars result = willCollide(collection[i], collection[j]);
      if (result.time != -1) {
        collision.push_back(result);
      }
    }
  }
  sort(collision.begin(), collision.end(), tupleCompare); // where goes wrong
}

如果你想知道,我在struct中使用reference来确保Car传入struct的任何更改都会反映在vector&lt;汽车&gt;集合

我已经更改了对指针的引用,但现在它给了我新的错误消息,如下所示

cannot convert ‘Car’ to ‘Car*’ in initialization
       return collisionOfCars{car1, car2, sol1};

1 个答案:

答案 0 :(得分:1)

为了使std::sort()起作用,必须为要排序的对象类型(std::swap())实例化collisionOfCars。为了实现这一点,它必须是复制或移动可分配的(或具有std::swap()特化)。您的类型不声明任何运算符,并且编译器不会为您生成一个,因为您的类型不符合生成运算符的要求。

这是因为该类型具有引用类型的非静态数据成员。 (请记住,引用不能重新设置,因此无法交换两个引用,以便它们引用不同的对象 - 您只能交换引用对象的内容,这不是什么你想要。)

  

如果满足以下任何条件,则类T的默认复制赋值运算符被定义为已删除

     

...

     
      
  • T具有引用类型的非静态数据成员;
  •   

Source

  

如果满足以下任何条件,则T类的隐式声明或默认移动赋值运算符被定义为 deleted

     

...

     
      
  • T具有引用类型的非静态数据成员;
  •   

Source

这意味着collisionOfCars个实例无法在彼此之上分配,这是必需来对矢量进行排序。 (如果不是通过交换元素在另一个上面,如何对矢量进行排序?)

最简单的解决方案是将collisionOfCars更改为使用Car *(指向 - Car)而不是Car &(引用至Car )。你也可以使用std::reference_wrapper<Car>(它只是一个指针的包装器)。