在哪种情况下,(a = b)是个好主意?

Kla*_*aim 11 c c++

可能重复:
无意中使用=而不是==

C++编译器通过您编写的警告让您知道

if( a = b ) { //...
Run Code Online (Sandbox Code Playgroud)

并且这可能是一个错误,你当然想写

if( a == b ) { //...
Run Code Online (Sandbox Code Playgroud)

但有没有一种情况应该忽略警告,因为这是使用这个"功能"的好方法?我没有看到任何代码清晰度可能的原因,那么它有用吗?

Cam*_*Cam 17

两个可能的原因:

  1. 分配和检查

    =操作者(当没有覆盖)通常返回其分配值.这是为了允许诸如此类的陈述a=b=c=3.在您的问题的上下文中,它还允许您执行以下操作:

    bool global;//a global variable
    
    //a function
    int foo(bool x){
    
       //assign the value of x to global
       //if x is equal to true, return 4
       if (global=x)
           return 4;
    
       //otherwise return 3
       return 3;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    ...相当于但短于:

    bool global;//a global variable
    
    //a function
    int foo(bool x){
    
       //assign the value of x to global
       global=x;
    
       //if x is equal to true, return 4
       if (global==true)
           return 4;
    
       //otherwise return 3
       return 3;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    此外,应该注意(正如Billy ONeal在下面的评论中所述),当=操作符的左侧参数实际上是一个具有为可强制类型指定的转换运算符的类(隐式转换)时,这也可以工作.)一个布尔.换句话说,(a=b)将调整到true或者false如果a是一个可以强制转换为布尔值的类型.

    所以以下是与上面类似的情况,除了左手参数=是一个对象而不是一个bool:

    #include <iostream>
    using namespace std;
    
    class Foo {
    public:
        operator bool (){ return true; }
        Foo(){}
    };
    
    int main(){
        Foo a;
        Foo b;
    
        if (a=b)
            cout<<"true";
        else
            cout<<"false";
    }
    
    //output: true 
    
    Run Code Online (Sandbox Code Playgroud)

    注意:在撰写本文时,上面的代码格式会被窃听.我的代码(检查源代码)实际上具有适当的缩进,移位运算符和行间距.这&lt;应该是,并且不应该在每一行之间存在巨大的差距.

  2. 被覆盖的=运营商

    由于C++允许覆盖运算符,因此有时候=将覆盖除了原始类型之外的其他内容.在这些情况下,=对对象执行操作可能会返回一个布尔值(如果=是该对象类型的操作符被覆盖的话).

    所以下面的代码将执行=的操作ab作为参数.然后它会有条件地执行一些代码,具体取决于该操作的返回值:

    if (a=b){
       //execute some code
    }
    
    Run Code Online (Sandbox Code Playgroud)

    在这里,a必须是一个对象,b并且具有正确的类型,如=操作符覆盖a的类型对象所定义的那样.要了解有关运算符覆盖的更多信息,请参阅此维基百科文章,其中包含C++示例:维基百科有关运算符覆盖的文章

  • 我认为第二种形式(覆盖=返回布尔值)是可怕的,邪恶的,丑陋的,并且使你成为一个坏人. (6认同)
  • 因为每个人都希望a = b返回值本身.想象一下,试着写一个= b = c = d; 当你想为彼此分配一堆变量时...然后计算出10个小时的破坏之后b = c返回1而不是c!它违反了=运算符的一般契约. (3认同)

Ste*_*ker 11

while ( (line = readNextLine()) != EOF) {
    processLine();
}
Run Code Online (Sandbox Code Playgroud)

  • 但是,这并不是真正相同的情况,因为您没有直接使用该任务作为测试. (18认同)
  • 不,它是一个赋值结果,用作比较表达式的左侧,用作if语句的求值表达式.它客观上不一样,因为编译器永远不会警告这种形式. (7认同)
  • 这不是同一种情况.使用`!=`比较来评估实际的if条件. (4认同)
  • 不,它确实是相同的情况:赋值结果作为if()语句的求值表达式. (3认同)

Ed.*_*Ed. 8

您可以用来测试函数是否返回任何错误

if (error_no = some_function(...)) {
    //handle error
}
Run Code Online (Sandbox Code Playgroud)

假设some_function在发生错误时返回错误代码,否则返回零


lor*_*ova 6

这是C语言基本功能的结果:

赋值操作的值是指定值本身.

您可以使用"返回值"作为if()语句条件的事实是偶然的.

顺便说一句,这是同样的技巧,允许这种疯狂的简洁:

void strcpy(char *s, char *t)
{
    while( *s++ = *t++ );
}
Run Code Online (Sandbox Code Playgroud)

当然,while t到达nullchar时退出,但同时将其复制到目标s字符串.

这是否是一个好主意,通常不是,因为它降低了代码的可读性并且容易出错.