C++ 建议在赋值周围使用括号作为真值

C++ suggest parentheses around assignment used as truth value

我的这部分代码有一些问题:

Employees.cpp:

void Employees::delete_employee()
{
    int employee_number;

    cout<<"\n..."<<endl<<endl;
    cout<<"Give me the number:";
    cin>>Employee_number;

    for(std::vector<EmployeeStruct>::size_type i = 0; i != lista.size(); i++)
        {
            if (employee_number = lista[i].Employee_number)
            {
                lista.erase(lista.begin() + i);
            }
        }
    cout<<"..."<<endl<<endl;
    cout<<"--------------------------------"<<endl;

}

当我编译我的代码时,我看到类似的东西:警告:建议在赋值周围使用括号作为真值 [-Wparentheses] 我真的不知道该怎么做接着就,随即。也许这不是一个严重的问题,但我的程序没有按我想要的方式运行。 (此代码应删除员工)

main.cpp我有:

    case 4:
        {
            Pracownicy p;
            p.usun_pracownika();
        }
    break;

也许有人可以帮助我。

我认为这是一个非常常见的错误:

if (employee_number == lista[i].Employee_number)
                    ^^
{
     lista.erase(lista.begin() + i);
}

您在这里将布尔检查 == 运算符与 = 赋值运算符混淆了,可能是拼写错误或错误。

I'm realy don't know what to do with that.

使用相等比较而不是赋值,这就是大多数情况下警告的最终建议:

 if (employee_number == lista[i].Employee_number)
                  // ^^

或者在

两边用括号明确说明你想要什么
if ((employee_number = lista[i].Employee_number))

虽然编译器没有这么好的警告。

I'm realy don't know what to do with that.

这取决于你打算做什么。

如果您不打算分配,而是比较相等性,那么您应该修改代码以使用相等运算符:==

如果您确实打算赋值,那么您可以:a) 忽略警告或 b) 添加括号,告诉编译器您确实打算进行赋值并且这不是错误。或者正如 Christian Hackl 评论的那样 c) 将赋值和比较分成两个语句以提高可读性。

您的代码中还有另一个错误。擦除将其余元素左移。下一个元素不再位于 i++,因此您最终会在擦除后跳过元素。如果擦除一个以上的元素,这也是低效的。有关更好的方法,请参阅 erase-remove idiom

一个简单的错误。您写道:

 if (employee_number = lista[i].Employee_number)

if (employee_number == lista[i].Employee_number)

您这边的主要问题是无意中使用了赋值运算符 = 而不是预期的比较 ==.

在语言方面,这个常见问题是通过从原始 C 继承的两个增强风险的功能实现的,即正式的 条件 接受任何转换为​​ [=14 的对象=],并且为了支持多重赋值,赋值是一个表达式而不是一个语句。

您很幸运能够使用产生 警告 的编译器和选项进行编译:无法保证会出现此类警告。


一个保证得到 error 的方法是让左边是一个不能赋值的表达式,例如

  • 在有意义的地方自由使用const

在给定的情况下,而不是

void Employees::delete_employee()
{
    int employee_number;

    cout<<"\n..."<<endl<<endl;
    cout<<"Give me the number:";
    cin>>Employee_number;

    for(std::vector<EmployeeStruct>::size_type i = 0; i != lista.size(); i++)
        {
            if (employee_number = lista[i].Employee_number)
            {
                lista.erase(lista.begin() + i);
            }
        }
    cout<<"..."<<endl<<endl;
    cout<<"--------------------------------"<<endl;

}

你可以做得更安全

auto fail() -> bool ...;

auto line_from( istream& stream )
    -> string
{
    string line;
    getline( stream, line )
        or fail();
    return line;
}

void Employees::delete_employee()
{
    cout<<"\n..."<<endl<<endl;
    cout<<"Give me the number:";
    int const Employee_number = to_string( line_from( cin ) );

    for(std::vector<EmployeeStruct>::size_type i = 0; i != lista.size(); i++)
        {
            if (employee_number == lista[i].Employee_number)
            {
                lista.erase(lista.begin() + i);
            }
        }
    cout<<"..."<<endl<<endl;
    cout<<"--------------------------------"<<endl;

}

如果使用 == 而不是 =,此代码将根本无法编译,并且作为奖励,使用 getline 有助于避免从 cin.


另一种修复方法是通过宏重新定义 if,或定义扩展为安全使用 if 的宏。第一个在技术上是可行的,但如果包含任何标准库头文件,则形式上是未定义的行为,通常是这种情况。第二个是严重的(通常是不可接受的)代码丑化,并且会使维护成为一场噩梦。我记得曾经为其中一个 Unix shell 做过类似的事情。由于除了原始程序员之外没有人理解任何代码,因此它的生命很短暂。