Reputation: 1103
There are quite a few posts on SO with similar titles, but they seem to be triggered by various syntactic errors and I didn't see a consistent pattern yet..
using namespace std;
class A
{
public:
A(int a_) : a(a_) {}
int a;
};
int main()
{
A x{3};
A y{0};
if ((y=x).a)
cout << y.a << endl;
int i = 1;
if (int j = i)
cout << j << endl;
if ((A z = x).a) // error: expected primary-expression before ‘z’
cout << z.a << endl;
(int m = 1); // error: expected primary-expression before ‘int’
}
Am I wrong to assume A z = x
is an assignment expression, which should have the same value as z
?
Upvotes: 0
Views: 4072
Reputation: 16841
Am I wrong to assume
A z = x
is an assignment expression
Yes, you are wrong. There is no assignment going on here. The =
in this statement represents initialization, not assignment. The statement A z = x;
defines the variable z
, where z
is constructed from x
. The copy constructor is used here, not copy assignment. It is a declaration statement, not an expression statement.
Your confusion is reasonably common, and it is made worse by the fact that the condition in an if
statement can be a declaration of a single non-array variable with a brace-or-equals initializer. Syntactically, a declaration with an "equals" initializer can look a lot like an assignment. A big difference, as you discovered, is that you cannot treat the declaration as a sub-expression. The condition is either a declaration or an expression, not a mix of both.
The good news is that C++-17 added an optional init-statement to the if
statement syntax. So what you appear to want would be achieved by the following.
if ( A z = x; z.a ) // Semicolon separates init-statement from condition
cout << z.a << endl;
// At the end of the `if` statement, `z` goes out of scope.
Upvotes: 5
Reputation: 25388
You can't declare a variable in an if
statement in that fashion. The declaration has to be of the form:
if (X x = y) ...
(or if (auto x = y) ...
)
However, you can still achieve what you are trying to do if you provide a suitable conversion operator in class A
, like this:
#include <iostream>
using namespace std;
class A
{
public:
A(int a_) : a(a_) {}
int a;
operator bool () { return a != 0; }
};
int main()
{
A x{3};
const A &y = x;
if (y.a)
cout << y.a << endl;
if (A z = x)
cout << z.a << endl;
}
Upvotes: 3