预期 primary-expression 在‘...’之前,C++ 编译错误

expected primary-expression before ‘...’, c++ compile error

SO 上有很多标题相似的帖子,但它们似乎是由各种语法错误触发的,我还没有看到一致的模式..

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’
}

我假设 A z = x 是一个赋值表达式,它应该与 z 具有相同的值吗?

您不能以这种方式在 if 语句中声明变量。声明必须采用以下形式:

if (X x = y) ...(或if (auto x = y) ...

但是,如果您在 class A 中提供合适的转换运算符,您仍然可以实现您想要做的事情,例如:

#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;
}

Live demo

Am I wrong to assume A z = x is an assignment expression

是的,你错了。这里没有任务。该语句中的 = 表示初始化,而不是赋值。语句 A z = x; 定义变量 z,其中 z 是从 x 构造的。这里用的是拷贝构造函数,不是拷贝赋值。是declaration statement,不是表达式语句

您的困惑相当普遍,并且由于 if 语句中的条件可以是带有大括号或等于初始值设定项的单个非数组变量的声明这一事实使情况变得更糟。从句法上讲,带有“等于”初始值设定项的声明看起来很像赋值。正如您所发现的,一个很大的区别是您不能将声明视为子表达式。条件是一个声明一个表达式,不是两者的混合

好消息是 C++-17 在 if 语句语法中添加了一个可选的 init-statement。因此,您似乎想要的可以通过以下方式实现。

    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.