Variable changes on it's own in C++ - c++

I have a loop going through an array trying to find which index is a string. It should solve for what that value should be.
I can't figure out why, but as soon as the if statements start i becomes 1 which gives my code an error.
I'm not very fluent in C++.
for(int i = 0; i < 4; i++) {
if(auto value = std::get_if<std::string>(&varArr[i])) {
solvedIndex = i;
auto value0 = std::get_if<float>(&varArr[0]);
auto value1 = std::get_if<float>(&varArr[1]);
auto value2 = std::get_if<float>(&varArr[2]);
auto value3 = std::get_if<float>(&varArr[3]);
//i changes to 1 when this if starts??
if(i = 0) {
solvedVar = (*value3 / *value1) * *value2;
} else if (i = 1) {
solvedVar = *value3 / (*value0 / *value2);
} else if (i = 2) {
solvedVar = *value0 / (*value3 / *value1);
} else {
solvedVar = *value1 * (*value0 / *value2);
}
break;
}
}
Note that these variables are declared above. Also, varArr is filled with values:
std::variant<std::string, float> varArr[4];
int solvedIndex;
float solvedVar;

As has been noted, in your if statements, you are using the assignment operator (=) but want the equality comparison operator (==). For your variable i the first if statement sets i equal to 0 and if(0) is the same as if(false). So your program goes to the first else-if which sets i equal to 1 and if(1) evaluates to true. Your code then finishes the block within else if (i = 1) {...} and then ends.

That's because operator= is the assignment operator in C++ (and most languages, actually). That changes the value of the variable to the value on the other side. So, for instance:
x = 0
will change the value of x to 0. Doesn't matter if it's in an if statement. It will always change the value to 0 (or whatever the right hand side value is).
What you are looking for is operator==, which is the comparison (aka relational) operator in C++/ That asks the question "Are these two things equal?" So, for instance:
x == 0
asks is x is equal to 0.

Related

What happens due to & operator in the following case?

I have known, '&' as bitwise and as an operator to get memory address of a variable.
What happens in this case of the code?
res = res & (a[i]<[a[i+1]]);
If it is bitwise and , as far as I know the second condition is also checked,
but what if I used logical and instead of it , wouldn't it still be the same?
As first part is (say) false , second parts get checked comes true, but still res remains false.
Would it be same (for this case) to use logical and for this? or it has some other use (& operator) for this case?
int a[] {1,3,4,2};
int pos = 3;
bool res = true;
for(int i = 0; i < pos; i++)
res &= (a[i] < a[i + 1]);
(Sorry for bad english)
If it is bitwise and , as far as I know the second condition is also checked, but what if I used logical and instead of it , wouldn't it still be the same?
No. Boolean and (written as && or and) has short circuit evaluation - if left part is false right part is not evaluated at all. This allows to write code like this:
if( pointer != nullptr && pointer->value > 100 ) ...
if not short circuit evaluation this code would have UB. For example this code:
if( pointer != nullptr & pointer->value > 100 ) ...
has Undefined Behaviour when pointer is equal to nullptr
Would it be same (for this case) to use logical and for this? or it has some other use (& operator) for this case?
You cannot, as there is no &&= operator in C++. You can write:
res = res && (a[i] < a[i + 1]);
and that would have short circuit as well and compiler may even be smart enough to stop the loop, though I doubt and it should be expressed explicitly anyway:
bool res = true;
for(int i = 0; res && i < pos; i++)
res = a[i] < a[i + 1];
which does the same, but cleaner and more efficient.
Anyway when you need logical or boolean and you should use one to make your intention clear and avoid unexpected surprises.
Besides the short circuiting issue, If res == 2 then:
res & 1 will return 0 which will be interpreted as false.
res && 1 will return true.
Your question is not clear.
Okay, let's dive into your code.
Your given code is very clear. You are performing bitwise and for pos(3) times. For every loop you are comparing a[i] with a[i+1]. Please note that for the last loop, I mean when variable i becomes 3, then i+1 will be 4. And your array a[] doesn't have a[4]. It only has the last element having index 3.
So for bitwise and operation the value of res isn't predictable as a[4] isn't defined.
Now let's think about logical AND operation. For logical and your expression inside the for loop will once generate a false boolean value for a[i] < a[i+1] as your array a[] = {1,3,4,2}. Here 4>2 not 4<2. Hence it will generate false boolean value and your entire response will be false 'cause you know logical AND will be eventually 0 if one of the operands is false.
I think you have got this.

What is the meaning of A += B == 1

I have came across one type of usage of operator =. It was something like this:
A += B == 1;
where A and B are integers and this kind of usage I found in a function body.
I just kind of confused with the second == usage.
Of course I know the meaning of A = B = 1;
Can anybody explain me?
This code:
A += B == 1;
is logically equal to:
bool b = B == 1;
A += b;
Note: bool can be implicitly converted to int (true to 1 and false to 0)
== has higher precedence over +=, so it's executed first
B == 1 is a boolean expression, can be false or true
let's call that bool 'result'.
A += result is an addition + assignment (like A = A + result as you may already know).
Since A is an int in your case, the boolean result is implicitly converted to the number 1 if true, or 0 if false. (it would work similarily for other number types as well)
More on implicit conversions here : http://en.cppreference.com/w/cpp/language/implicit_conversion
So, at the end, this is logically equivalent to "increment A if and only if B is equal to 1" :
if (B == 1)
A += 1;

the result of assignment Logic operation [duplicate]

This question already has answers here:
In C++ what causes an assignment to evaluate as true or false when used in a control structure?
(6 answers)
Closed 5 years ago.
int a = 5;
if(a = 5)
{
cout<<"111111"<<endl;
}
if(a = 0)
{
cout<<"22222"<<endl;
}
the reslut is
111111
Press any key to continue
acrroding to some commments,assign success,the result is true。
"a = 0" and a = 1" should assign success.but the result is only the first executed....
why ?
Some comments? That seems dodgy and in this case is incorrect.
The result of operator= on ints is the value that has been assigned. In this case a = 5 results in 5 and a = 0 results in 0. Since 5 evaluates as true you see "111111" but since 0 evaluates as false you don't see "22222".
As for why assignment results in the value being assigned, take the case with multiple assignments:
a = b = 5;
This is the same as:
a = (b = 5);
So for this to work as expected (b = 5) must return 5.
The result of a=5 is 5, and the result of a=0 is 0, so your program is like:
int a = 5;
if(5)
{
cout<<"111111"<<endl;
}
if(0)
{
cout<<"22222"<<endl;
}
Since the if statement requires a boolean value, 5 converts to true and 0 converts to false implicitly. so your program is now like:
int a = 5;
if(true)
{
cout<<"111111"<<endl;
}
if(false)
{
cout<<"22222"<<endl;
}
So it will print "111111" only.
"acrroding to some commments,assign success,the result is true"
The result of assignment is the result of expression in the left side.
"a = 0" and a = 1" should assign success.but the result is only the first executed....
Nope. 0 is false, you may as well have written"
if(0) { /* some code which will never execute */ }
The if statement evaluates the result of the expression between the parentheses, which means that the expression itself must be evaluated completely before the condition is checked.

What sense could have this code?

I´m studing the code of OpenCV, and I came across the next few lines:
The function´s var are:
CvMat* _err;
CvMat* _mask;
int i, count = _err->rows*_err->cols, goodCount = 0;
for( i = 0; i < count; i++ )
goodCount += mask[i] = err[i] <= threshold; // This line is strange for me
return goodCount;
What does the line I indicated actually do? Because, call me strange, I have never seen anything like that.
For your information:
Yes, the code is working :D
The code is part of the CvModelEstimator2::findInliers function.
That line is evil.
Nevertheless, it assigns 1 to mask[i] if err[i] <= threshold and 0 otherwise.
Then it increments goodCount if the condition holds.
mask[i] = (err[i] <= threshold);
goodCount += mask[i];
So you're confused about this line:
goodCount += mask[i] = err[i] <= threshold;
You can use a C operator precedence table to figure out the order of operations here, but it's fairly unambiguous anyway:
Compare err[i] against threshold. This results in a bool (true or false).
Assign the result to mask[i]. I think the bool will be converted to a number here, which will be 1 for true or 0 for false.
Use the new value of mask[i] (which is the result of the = operator) to increment goodCount (basically, goodCount will end up containing the count of "true" values found in step 1).
To me the most subtle part of that line is the fact that assignment returns a reference to the left-hand side (i.e. the target). This is sometimes seen in a less complex expression like this:
if ((mem = malloc(42)) == NULL)
throw ...
goodCount += mask[i] = err[i] <= threshold;
Mixing assignment and comparison in the same statement is generally a bad idea.
The recommended approach is to (1) know what is the precedence of the involved operators, and (2) split the statement into several ones, to enhance readability.

C++ Operator (unsure of)

Is there a c++ operator that i could use for a for loop where it would add or subtract to variables based on whether one of the variables is less than or greater 0.
For instance
int a;
int b;
for(int i=0;i<some_number; i++)
result = a +< b
result = a-> b
No.
You can combine with the ?: operator.
int a;
int b;
for(int i=0;i<some_number; i++)
result = (a < b)? result+b:result-b;
That is if I understood your example correctly.
-> is an existing dereference operator.
Operator ?: is an equivalent to the if...else construct. If the statement before ? evaluates to true, the statement right after the ? gets executed, otherwise the statement after the : gets executed.
Do you want something like this?
result += a > 0 ? b : -b;
Note that this will subtract b if a == 0, which isn't quite what you asked for.
Not directly, but the ternary operator is close.
for(int i=0;i<some_number; i++)
result = (a > 0)?(a):(b);
This line will be equivalent to result = a when a is greater than 0, and result = b elsewise.
It could also be written as result = a?a:b;, but the longer form is more readable.
Not sure if this would be any help?
result = a + (b*(a < b));
result = a - (b*(a > b));
Basically, (a < b) is converted into a boolean, which is basically either 1 (true) or 0 (false). b multiplied by 0 is of course zero, so nothing is added, and b multiplied by 1 is exactly b's value.