Box2D vector () operator - c++

I was reading the Box2D source code. In b2Vec2 there is the () operator being overloaded, but I did not understand what it is supposed to do. I read the manual and the reference of this method but still did not get what it means to Read from an indexed element and write to an indexed element, and both methods have the same body return (&x)[i]. What does this mean and do?

Thanks to a previous comment (but it was removed for some reason), I got an idea and tested it out, and it turns out this will allow me to access and write to x and y using indices 0 and 1 respectively.
For example:
#include <iostream>
using namespace std;
class clazz {
public:
float x, y;
clazz(float x_, float y_) : x(x_), y(y_) {}
float operator () (int i) const {
return (&x)[i];
}
float& operator () (int i) {
return (&x)[i];
}
};
int main() {
clazz f (3, 4);
cout << "f: x = " << f(0) << " y = " << f(1) << endl; // printed => f: x = 3 y = 4
f(0) = 6;
f(1) = 6;
cout << "f: x = " << f(0) << " y = " << f(1) << endl; // printed => f: x = 6 y = 6
return 0;
}

As you found out it's an accessor function to the individual elements in the vector class. The reason there are two functions is due to const functions need access to the value of the element without needing to modify it. Note that you could return a const reference here as well but this is not necessary in your case since it is operating on a float.
Hopefully there are asserts in place for making sure that code isn't indexing out of the range since that is quite easy to do, especially when you have are using a signed variable like in your example.

Related

Assign TicTacToe player position to a bitboard representation

I have 2 separate boards for 2 players: X and O. Now I'd like to make sure if an entered position (int x, int y) is valid but I've got no idea of how should I convert it to bitboard representation and compare it with given board states and it's doing me head in. Also wrote a helper function to see the board states bin(). And is there a way to merge the X and O boards into one or should I keep the separate all board to check the game state?
#include <bits/stdc++.h>
using namespace std;
bool xmove = true;
const int win[] = { 0b111000000,
0b000111000,
0b000000111,
0b100100100,
0b010010010,
0b001001001,
0b100010001,
0b001010100 };
struct Board {
int b = 0b000000000;
};
int iswin(int x) {
for (size_t i = 0; i < 8; i++) {
if (win[i] == x) return 1;
}
return 0;
};
void bin(int x){
cout << "0b" + bitset<9>(x).to_string() << endl;
};
int main() {
Board x, o, all;
x.b |= 0b000000111;
o.b |= 0b000111000;
all.b = x.b | o.b;
bin(all.b);
cout << iswin(x.b);
return 0;
}
Well you can treat your bitstring as a flattened 2d array. To convert a 2d index into a 1d one you can simply do
x * width + y
So to set the matching position in the board you can do
int move = 1 << (x * 3 + y)
since a TicTacToe board is 3 wide and 3 tall. You can then check if there already is an X or O at that position with
if(x.b & move)
{
std::cout << "there already is and x at(" << x << ", " << y << ")";
}
To then add that position to the board if there is nothing there do
x.b |= move
Same thing for o.b. This is of course based on the assumption that your x and y start at 0.
Concerning your question of whether or not you can merge the two board. How would you even do that? A bit can only be 0 or 1 so there is no way to differentiate between 3 different states (nothing, X, O).

Is there a way to swap 2 structs?

In c++ you can swap 2 numbers without 3rd variable:
int x = 10;
int y = 5;
x ^= y;
y ^= x;
x ^= y; //x = 5, y = 10
So I wonder if there is a similar way to swap 2 structs without 3rd variable:
struct Position{int x, y;};
int main()
{
Position firstPose{x = 10, y = 5;};
Position secPose{x = 5, y = 10;};
//Now I want to swap firstPose with secPose.
}
Is this possible? if so; how to do it
There is no a standard way to swap two structure without an intermediate copy. Arguably, one of the main benefit of swap "is" the intermediate copy, this wonderful article explain how swap is a crucial part to achieve "strong exception guarantee". https://www.stroustrup.com/except.pdf
Furthermore, if the goal is to not make a copy of the struct (because is resource intensive) you can design your class using the pimpl idiom and swap just the pointer (you will still have a third variable but it will be just the raw pointer to the structure).
If you want to use C++ effectively make yourself familiar with exception safety, it is truly of of the area where the language gives its best
A bit old but still good article: http://www.gotw.ca/gotw/008.htm
At the end, the final solution is create a custom swap function:
#include <iostream>
#include <string>
struct Position{int x, y;};
void swap(Position& a, Position& b)
{
a.x ^= b.x;
b.x ^= a.x;
a.x ^= b.x;
a.y ^= b.y;
b.y ^= a.y;
a.y ^= b.y;
}
int main()
{
Position a = { 10, 100};
Position b = { 20, 200};
swap(a, b);
std::cout << "a:" << a.x << "," << a.y << std::endl;
std::cout << "b:" << b.x << "," << b.y << std::endl;
}
IMHO, the last option is more for personal amusement than real production code.
Yes, there are some ways to achieve your requirement. But, note that the XOR method of swapping between two values is quite inefficient.
First of all, let's assume the required struct:
struct position {
int x;
int y;
};
Method 1
Create your own swap() function:
void swap(position &pos1, position &pos2) {
// Swapping X
verify_overflow(pos1.x, pos2.x); // See about this below
pos1.x = pos1.x + pos2.x;
pos2.x = pos1.x - pos2.x;
pos1.x = pos1.x - pos2.x;
// Swapping Y
verify_overflow(pos1.y, pos2.y); // See about this below
pos1.y = pos1.y + pos2.y;
pos2.y = pos1.y - pos2.y;
pos1.y = pos1.y - pos2.y;
}
Now, you can implement it like this:
swap(v1, v2);
Note: To prevent undefined-behavior due to the overflows, the following subroutine could be used:
inline void verify_overflow(signed int si_a, signed int si_b) {
signed int sum;
if (__builtin_sadd_overflow(si_a, si_b, &sum)) {
std::cerr << "[error] Overflow is possible to happen.\n";
exit(1);
}
}
For example, when you set a struct:
position v1 = {2147483647, 2147483644};
The program will yield the following error, then UB won't occur:
[error] Overflow is possible to happen.
Method 2
There is already a built-in std::swap() in C++ standard. Its benefit is that you won't need to keep changing the code when the struct alters. The code should look like this:
#include <iostream>
struct position {
int x;
int y;
};
int main(void) {
position v1 = {5, 10};
position v2 = {10, 5};
std::swap(v1, v2);
std::cout << v1.x << ' ' << v1.y << std::endl;
std::cout << v2.x << ' ' << v2.y << std::endl;
return 0;
}

Why is int x{ y = 5 } possible?

int main() {
int y;
int x{ y = 5 };
//x is 5
}
How is this possible, since y = 5 is not a calculable expression?
Also, why doesn't the compiler or IDE complain about main() not returning an int?
How is this possible, since y = 5 is not a calculable expression?
It is an assignment, and assignments yield values, i.e. the "cv-unqualified type of the left operand", see [expr.ass/3]. Hence y = 5 results in y, which is 5, which is used to initialize x.
With respect to your second question, see cppreference on main (or [basic.start.main/5]):
The body of the main function does not need to contain the return statement: if control reaches the end of main without encountering a return statement, the effect is that of executing return 0;.
Hence, compiler or IDE warning you about a missing return statement at the end of main would be plain wrong. Admittedly, the fact that you should always return objects from non-void functions execpt main is kind of... well, for historical reason I guess.
I will start from your last question
Also, why doesn't the compiler or IDE complain about main() not
returning an int?
According to the C++ Standard (6.6.1 main function)
5 A return statement in main has the effect of leaving the main
function (destroying any objects with automatic storage duration) and
calling std::exit with the return value as the argument. If control
flows off the end of the compound-statement of main, the effect is
equivalent to a return with operand 0 (see also 18.3).
And relative to this question
How is this possible, since y = 5 is not a calculable expression?
From the C++ Standard (8.18 Assignment and compound assignment operators)
1 The assignment operator (=) and the compound assignment operators
all group right-to-left. All require a modifiable lvalue as their left
operand and return an lvalue referring to the left operand.
Sp this declaration
int x{ y = 5 };
can be equivalently split into two statements
y = 5;
int x{ y };
Moreover in C++ you can even to make a reference to the variable y the following way
int &x{ y = 5 };
Here is a demonstrative program
#include <iostream>
int main()
{
int y;
int &x{ y = 5 };
std::cout << "y = " << y << '\n';
x = 10;
std::cout << "y = " << y << '\n';
}
Its output is
y = 5
y = 10
You may this declaration
int x{ y = 5 };
rewrite also like
int x = { y = 5 };
However take into account that there is a difference between these (looking similarly as the above declarations) two declarations.
auto x{ y = 5 };
and
auto x = { y = 5 };
In the first declaration the variable x has the type int.
In the second declaration the variable x has the type std::initializer_list<int>.
To make the difference more visible see how the values of the objects are outputted.
#include <iostream>
int main()
{
int y;
auto x1 { y = 5 };
std::cout << "x1 = " << x1 << '\n';
auto x2 = { y = 10 };
std::cout << "*x2.begin()= " << *x2.begin() << '\n';
std::cout << "y = " << y << '\n';
return 0;
}
The program output is
x1 = 5
*x2.begin()= 10
y = 10
The operator=() results in a value, which is the value assigned to the variable. Because of this, it is possible to chain assignments like this:
int x, y, z;
x = y = z = 1;
If you take a look at the documentation on cppreference, you'll see that operator=() return a reference to the object that was assigned. Therefore, a assignment can be used as an expression that returns the object that was assigned.
Then, it's just a normal assignment with braces.

Why does this seemingly simple C++ code generate a segmentation fault?

I'm trying to write a boosting algorithm (a feature of artificial intelligence). Speed is a priority, so I've switched from using my native Python to C++. I wrote the entire program out, but I got a bug that I whittled down to a fault I made in the base class: a very simple heuristic called "H." The files h.h, h.cpp, and my current testing function main.cpp are:
//h.h
#ifndef __H_H_INCLUDED__
#define __H_H_INCLUDED__
#include <iostream>
#include <vector>
class H
{
public:
H(int, double, bool);
//The first parameter is the axis
//The second parameter is the cutoff
//The third parameter is the direction
bool evaluate(std::vector<double>&);
//This evaluates the heuristic at a given point.
private:
int axis;
double cutoff;
bool direction;
};
#endif
//h.cpp
#include "h.h"
H::H(int ax, double cut, bool d)
{
axis = ax;
cutoff = cut;
direction = d;
}
bool H::evaluate(std::vector<double>& point)
{
if (direction)
{
return point[axis] > cutoff;
}
else
{
return point[axis] <= cutoff;
}
}
//main.cpp
#include <iostream>
#include <vector>
#include "h.h"
int main()
{
H h(0, 2.0, true);
for (double x = 0; x < 4; x = x + 1)
{
for (double y = 0; y < 4; y = y + 1)
{
std::vector<double> point(x, y);
std::vector<double>& point_ref = point;
std::cout << "Before computation" << std::endl;
bool value = h.evaluate(point_ref);
std::cout << "After computation" << std::endl;
std::cout << "heuristic(x = " << x << ", y = " << y << ") = " << value << std::endl;
}
}
return 0;
}
(I put the "Before computation" and "After computation" in to pinpoint which line the error occurs on.) Quite contrary to the output I would expect, I get:
Before computation
Segmentation fault (core dumped)
What did I do wrong? What does that error message even mean?
Thanks!
EDIT: I'm using C++11, just for those who are curious.
This line:
std::vector<double> point(x, y);
Makes a vector with x copies of y. It's constructor #2 here. So when x is 0, point is an empty vector - which means your access of the element at index 0 is undefined behavior, in this case exhibited by a segmentation fault.
What you probably had intended to do was to make a vector containing the two values x and y, which would be:
std::vector<double> point{x, y}; // in c++11, note the braces
std::vector<double> point(2); // pre-c++11
point[0] = x;
point[1] = y;

Jumping into C++ Chapter 13 Practice Prob No4 - Pointers

I've having trouble understanding the wording of this question and what it means by returning the second value through a pointer parameter?
The problem is:
Write a function that takes input arguments and provides two seperate results to the caller, one that is the result of multiplying the two argumentsm the other the result of adding them. Since you can directly return only one value from a funciton you'll need the seecond value to be returned through a pointer or references paramter.
This is what I've done so far.
int do_math(int *x, int *y)
{
int i =*x + *y;
int u = *x * *y;
int *p_u = &u;
return i;
}
void caller()
{
int x = 10;
int y = 5;
std::cout << do_math(&x, &y);
//std::cout << *u;
}
I think all they're wanting you to do is to demonstrate your understanding of the difference between passing arguments by value and passing them by reference.
Here is a sample code that shows that although my function is only returning one value "i = X+Y", It is also changing the value of Y to (Y * X).
Of course if you do need Y's value to stay unchanged, you could use a third variable that is equal to Y's value and pass its reference as an extra argument to your function.
You could run the code bellow to see what's happening to X and Y before and after calling the function.
Hope this helps.
#include <iostream>
using namespace std;
int do_math(int value1, int *pointer_to_value2)
{
int i = value1 * *pointer_to_value2;
*pointer_to_value2 = *pointer_to_value2 + value1; // y changes here
return i;
}
int main( int argc, char ** argv ) {
int x = 10;
int y = 5;
cout << "X before function call " << x << endl;
cout << "Y before function call " << y << endl;
int product = do_math(x, &y);
cout << "X after function call " << x << endl;
cout << "Y after function call " << y << endl;
cout << "What the function returns " << product << endl;
return 0;
}
In the assignment there is written
Write a function that takes input arguments ...
So there is no any need to declare these input parameters as pointers.
The function could look like
int do_math( int x, int y, int &sum )
{
sum = x + y;
return x * y;
}
or
int do_math( int x, int y, int *sum )
{
*sum = x + y;
return x * y;
}
In these function definitions the sum and the product can be exchanged as the parameter and return value
As for me the I would write the function either as
void do_math( int x, int y, long long &sum, long long &product )
{
sum = x + y;
product = x * y;
}
or
#include <utility>
//...
std::pair<long long, long long> do_math( int x, int y )
{
return std::pair<long long, long long>( x + y, x * y );
}
void caller()
{
int x = 10;
int y = 5;
std::pair<long long, long long> result = do_math( x, y );
std::cout << "Sum is equal to " << result.first
<< " and product is equal to " << result.second
<< std::endl;
}
Edit: I would like to explain why this statement
std::cout << "sum is " << do_math(x, y, result) << " and result is " << result;
is wrong.
The order of evaluation of subexpressions and function argument is unspecified. So in the statement above some compilers can output value of result before evaluation function call do_math(x, y, result)
So the behaviour of the program will be unpredictable because you can get different results depending on using the compiler.
Edit: As for your code from a comment then it should look like
#include <iostream>
int do_math( int x, int y, int *p_u )
{
int i = x + y;
*p_u = x * y;
return i;
}
int main()
{
int x = 10;
int y = 5;
int u;
int i = do_math( x, y, &u );
std::cout << i << std::endl;
std::cout << u << std::endl;
}
Also take into account that in general case it is better to define variables i and u as having type long long because for example the product of two big integers can not fit in an object of type int.
The wording is kind of contrived but I believe the task asks you to
return the multiplication as the return value of the function, and
since you can't return two types at once (except if you wrap them up somehow), you should use a third parameter as a storage area for the sum:
#include <iostream>
/* Multiplication in here */ int do_math(int x, int y, int& result/* Addition in here */)
{
result = x + y;
return x*y;
}
int main() {
int x = 10;
int y = 5;
int addition = 0;
int multiplication = do_math(x, y, addition);
std::cout << "multiplication is " << multiplication << " and sum is " << addition;
}
Example
It's not specifically asking you to use two parameters for the function.
A typical solution to the intent of the exercise text…
” Write a function that takes input arguments and provides two seperate results to the caller, one that is the result of multiplying the two argumentsm the other the result of adding them. Since you can directly return only one value from a funciton you'll need the seecond value to be returned through a pointer or references paramter
… is
auto product_and_sum( double& sum, double const a, double const b )
-> double
{
sum = a + b;
return a*b;
}
#include <iostream>
using namespace std;
auto main() -> int
{
double product;
double sum;
product = product_and_sum( sum, 2, 3 );
cout << product << ", " << sum << endl;
}
This code is unnatural in that one result is returned while the other is an out-argument.
It's done that way because the exercise text indicates that one should do it that way.
A more natural way to do the same is to return both, as e.g. a std::pair:
#include <utility> // std::pair, std::make_pair
using namespace std;
auto product_and_sum( double const a, double const b )
-> pair<double, double>
{
return make_pair( a*b, a+b );
}
#include <iostream>
#include <tuple> // std::tie
auto main() -> int
{
double product;
double sum;
tie( product, sum ) = product_and_sum( 2, 3 );
cout << product << ", " << sum << endl;
}
As the second program illustrates, the last sentence of the exercise text,
” Since you can directly return only one value from a funciton you'll need the seecond value to be returned through a pointer or references paramter
… is just not true. I suspect the author had meant the word “directly” to clarify that this excluded the case of a non-basic type. But even so the conclusion is incorrect.
What you need to do is provide another parameter to the function - the pointer or the reference to the variable where you want to store your other result:
int do_math(int *x, int *y, int &res) //or int *res
{
...
res = *x * *y;
...
}
Then make a result variable in main and pass it to the function