38. The trap of logical operators

The native semantics of logical operators: the operand has two values ​​(true and false), the logical expression can determine the final value without complete calculation, and the final result can only be true or false.

Can logical operators be overloaded?

#include <iostream>
#include <string>
using namespace std;
int func(int i)
{
    cout << "int func(int i) : i = " << i << endl;
    return i;
}
int main()
{
    if( func(0) && func(1) )
    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }
    cout << endl;
    
    if( func(0) || func(1) )
    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }    
    return 0;

}

Logical operators can be overloaded, traps:

#include <iostream>
#include <string>
using namespace std;
class Test
{
    int mValue;
public:
    Test(int v)
    {
        mValue = v;
    }
    int value() const
    {
        return mValue;
    }
};
bool operator && (const Test& l, const Test& r)
{
    return l.value() && r.value();
}
bool operator || (const Test& l, const Test& r)
{
    return l.value() || r.value();
}
Test func(Test i)
{
    cout << "Test func(Test i) : i.value() = " << i.value() << endl; 
    return i;int main()
}

{
    Test t0(0);
    Test t1(1);   
    if( func(t0) && func(t1) )                        //operatpr && ( func(t0), func(t1))

    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }  
    cout << endl;    
    if( func(1) || func(0) )                          //   operatpr || ( func(t0), func(t1))
    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }    
    return 0;

}

Analysis of the essence of the problem:

Before entering the function body, the two parameter values ​​must be determined. Regardless of the arguments, func is called twice. The order of evaluation is undefined. C++ extends the functionality of the operator through function calls. All parameter calculations must be done before entering the function body. The calculation of the function parameters is indeterminate, and the short-circuit law fails completely.

Logical operator overloading cannot achieve native semantics. suggestion:

In actual project development, overloading of logical operators should be avoided, by overloading comparison operators instead of logical operator overloading, directly using member functions instead of logical operations to send overloads, and using global functions to overload logical operators.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325953734&siteId=291194637