How to use std::any_of inside a class with lambda expression? - c++

I'm coding a small simulation in c++ with robots and I need to check if the robot are colliding. I implemented this function in my simulation's class:
bool World::isRobotColliding(Robot *r) {
for (Robot *other_robot: robots) {
double d = distance(r->getX(), r->getY(), other_robot->getX(), other_robot->getY());
if ((r->getRadius() + other_robot->getRadius()) >= d) return true;
}
return false;
}
double World::distance(const double &x_1, const double &y_1, const double &x_2, const double &y_2) const {
return sqrt((x_1 - x_2) * (x_1 - x_2) + (y_1 - y_2) * (y_1 - y_2));
}
Here my IDE suggested me to replace the for loop with the std::any_of() method. However, I was unable to use it properly. This is what I tried:
return std::any_of(robots.begin(), robots.end(), [r, this](const Robot *&other_robot) {
return
(r->getRadius() + other_robot->getRadius())
>=
distance(r->getX(), r->getY(), other_robot->getX(), other_robot->getY());
});
How can I use std::any_of() in my context?
Thank you

Thank you everyone for your advise,
The issue was the pointer passed by reference.
return std::any_of(robots.begin(), robots.end(), [r, this](const Robot *other_robot) {
double d = distance(r->getX(), r->getY(), other_robot->getX(), other_robot->getY());
if(d == 0) return false;
return
(r->getRadius() + other_robot->getRadius())
>=
d;
});
This snippet do exactly what I was expecting.
I needed to pass the first robot r in the context as well as this. I could have declared a distance function in my robot and ommiting the this.

Related

Program crashes without error message

I am using the Qt Creator (Community) to learn how to code.
I have an assignment to calculate the roots of a function, and I tried using the code I found here in a Qt Widgets Project.
When I try to run the program, Qt didn't detect any errors.
However, my program crashes whenever I try to show the results using on_pushButton_clicked().
My lecturer suspects there should be an open loop somewhere but I don't see any.
Any help would be very much appreciated.
Code below:
double function1(double q)
{
double ab = ((q*q*q)+(9*q*q)-(15*q)+98)*(sin(q));
return ab;
}
void MainWindow::on_pushButton_clicked()
{
ui->label->setText(tr("%1").arg(func1()));
}
double MainWindow::func1()
{
std::setprecision(4);
double precision = 0.001;
double a = -10;
double b = -9;
double product = function1(a)*function1(b);
double absolute = fabs(a-b);
double e = 0;
if (product>0)
{
++a;
++b;
}
else
{
while (absolute >= precision)
{
e = (a + b) / 2;
double fa = function1(a);
double fe = function1(e);
if (fe == 0)
{
return e;
break;
}
if (fa*fe>0)
{
a = e;
}
else if (fa*fe<0)
{
b = e;
}
}
}
return e;
}
Try printing out the values of absolute and precision everytime this loop happens:
while (absolute >= precision)
.
That should help you figure it out.
If the program crashes when you click the button that "calls" on_pushButton_clicked, then it something wrong inside this slot.
Firstly, are all heap memory objects created previously with a new statement (in particular label)?
PS: you can remove the break instruction, function has already exited the while loop due to return in the line before.

Using the method of an object in an ArrayList in an if statement

I'm trying to use a method from an object in an ArrayList, that's a parameter of a method... I'm not sure what the syntax is. It's the condition of the if where the problem is. It's not supposed to be Ship, but what else? .getSize() is a method in the Ship class. Or maybe this solution is totally off?
public void deployShips(char[][] board, ArrayList<Ship> fleet, int x, int y) {
if (Ship.getSize() == 5) {
int[] coordinate = coordinate(x, y);
board[coordinate[0]][coordinate[1]] = '+';
}
}
If i have understand what you need the code should be this:
n = the index postion of the object you need to call
fleet.get(n).theMethodYouNeed();
or if you need to check the entire list:
for(Ship ship: fleet){
if (ship.getSize() == 5) {
int[] coordinate = coordinate(x, y);
board[coordinate[0]][coordinate[1]] = '+';
}
}

Combining two lambdas in C++

I'm trying to write come code as follows. The aim is to provide a lambda function to be used elsewhere that converts position to velocity based on some user configurations.
base_vel = [=] (myVectorClass position) { return myVectorClass(0.0, 0.0); };
rand_vel = [=] (myVectorClass position) { return myVectorClass(0.0, 0.0); };
if (base_vel_type == vel_type::TYPE_1) {
base_vel = [=](myVectorClass position)
{ // code that finds velocity as a function of position
return myVectorClass(x, y); };
}
// more types
if (add_random == true);
rand_vel = [=](myVectorClass position)
{ // code that finds a random component to velocity
return myVectorClass(x, y); };
}
return base_vel + rand_vel;
Something isn't working correctly. I suspect that either the code inside the if statements is not overriding the previously declared lambda, or that my addition of the two lambdas at the end is not working as expected. How are lambda functions like this supposed to be amalgamated?
Thank you for any comments.
What you want appears to be:
return [=](myVectorClass position) { return base_vel(position) + rand_vel(position); };
As per #40two's suggestion: lambdas cannot be assigned and the OP would need to define base_vel and rand_vel (and the return of the mentioned but unnamed function) as
std::function<myVectorClass(myVectorClass)> base_rel = //...
std::function<myVectorClass(myVectorClass)> rand_vel = //...
std::function<myVectorClass(myVectorClass)> blah_blah_blah() {
//...
}
for those if statements to work :D

How do I get a variable from one function into another?

Exactly like the title says, how can I get my disc variable from my discr function into my calcRoots function?
// Function calculating roots
bool calcRoots(double coeffs[], int coeffLength, double roots[], int rootLength) {
if(disc >= 0) {
roots[rootLength - 1] = ((-(coeffs[coeffLength - 2]) + sqrt(disc)) / (2*(coeffs[coeffLength - coeffLength])));
roots[rootLength - rootLength] = ((-(coeffs[coeffLength - 2]) - sqrt(disc)) / (2*(coeffs[coeffLength - coeffLength])));
return true;
}
else {
return false;
}
}
// Solves the discriminant
double discr(double coeffs[], int coeffLength){
double disc = (pow(coeffs[coeffLength - 2],2)-4*coeffs[coeffLength - coeffLength]*coeffs[coeffLength - 1]);
return disc;
}
You didn't mention nay language but i supose to be C++.
Inside calcRoots you can make a call to discr and get the value to a variable like this:
double disc = discr(coeffs[], coeffLength);
Then use the value store in the variable. Hope this help.

Comparing variables in two instances of a class

i have what i hope is a quick question about some code i am building out.. basically i want to compare the variables amongst two instances of a class (goldfish) to see if one is inside the territory of another. they both have territory clases which in turn use a point clase made up of an x and y data-point.
now i was curious to know why the below doesnt work please:
(this bit of code compares two points: a & b, each with two points, a north-east (ne) and south-west (sw) and their x and y plots)
if ((a->x_ne <= b->x_ne && a->y_ne <= b-> ne) &&
(a->x_sw => b->x_sw && a->y_sw => b-> sw)) {
return true;
} else return false;
I can think of a work around (for instance, by having a get location method), and using a function in the main body to compare, but im curious to know --as a budding c++ programmer -- why the above, or a similar implementation doesnt appear to work.
and also, what would be the CLEANEST and most elegant way to accomplish the above? have a friend function perhaps?
many thanks
edit: added some comments to (hopefully make the variables clearer)
// class point {
// public:
// float x;
// float y;
// point(float x_in, float y_in) { //the 2 arg constructor
// x = x_in;
// y = y_in;
// }
// };
// class territory {
// private:
// point ne, sw;
// public:
// territory(float x_ne, float y_ne, float x_sw, float y_sw)
// : ne(x_ne, y_ne), sw(x_sw,y_sw) {
// }
// bool contain_check(territory a, territory b) {
// //checks if a is contained in b (in THAT order!)
// if ((a->x_ne <= b->x_ne && a->y_ne <= b-> ne) &&
// (a->x_sw => b->x_sw && a->y_sw => b-> sw)) {
// return true;
// } else return false;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// };
// class goldfish {
// protected:
// float size;
// point pos;
// territory terr;
// public:
// goldfish(float x, float y) : pos(x,y), terr(x-1,y-1,x+1,y+1) { //constructor
// size = 2.3;
// }
// void retreat() { //what happens in the case of loss in attack
// /*
// if(goldfish.size[1] - goldfish.size[2] <= 1 && goldfish.size[1] - goldfish.size[2] > 0) {
// size = size - 0.2;
// }
// */
// }
// void triumph() {
// }
// void attack() {
// }
// // void goldfish()
// };
On first glance: There isn't a => operator. It's called >=
Assuming that your territories are rectangles and your are detecting overlap by comparing the corners of the two classes (ne and nw) you are only checking the northwest and northeast corners which have a region of a line. As #Éric Malenfant mentioned, you have structures as the class members which are accessed by the '.' operator. Those members are ne and sw so to reference them would be: "a.ne.x"
So starting with this:
if ((a->x_ne <= b->x_ne && a->y_ne <= b-> ne) &&
(a->x_nw => b->x_nw && a->y_nw => b-> nw)) {
return true;
} else return false;
Change it to:
return ( (a.ne.x <= b.ne.x && a.ne.y <= b.ne.y)
&& (a.sw.x >= b.sw.x && a.sw.y >= b.sw.y));
What do you mean by "doesnt work"? I does not compile?
If contain_check is written as shown in your post, a problem is that you are using the arrow operator on non-pointers. Use dot instead:
if ((a.x_ne <= b.x_ne && a.y_ne <= b.ne) //etc.
I noticed two possible problems right off (note: not a C++ expert):
You use => for "greater than or equal to", where it should be >=.
Also, I think b->ne should be b->y_ne.
bool contain_check(territory a, territory b)
You're passing in two territory objects, not pointers to territory objects. Consequently, you'll want to use the . operator to access members instead of the -> operator. Something like:
a.ne
Additionally, you've declared the ne and sw members private, which means that they won't be accessible to unrelated functions. They would need to be public for the contain_check() function to access them.
sorry, i was clearly (very) confused. thanks guys! below works:
if ((a.ne.x <= b.ne.x && a.ne.y <= b.ne.y) &&
(a.sw.x >= b.sw.x && a.sw.y >= b.sw.y)) {
return true;
} else return false;
}
the method bool territory::contain_check(const territory &a, const territory &b); should be declared as static. it makes sense.
or, better, write it as standalone function, because it has nothing to do with the class territory; it checks some kind of relation between two instances, right?