简体   繁体   中英

why comma,address-of, logical AND and logical OR operators should not be overloaded in c++?

有人可以举例说明为什么在C ++中重载逗号,地址,逻辑与和逻辑或运算符不是一个好习惯吗?

The underlying reason is that overloaded versions of these operators behave differently than the builtin versions. This can lead to substantial confusion (of humans) reading/writing code.

  1. logical operators && and || The builtin versions exhibit short circuit optimisation: in an expression like a && b , a is evaluated first and only if true , b is also evaluated; similarly, in a || b a || b , a is evaluated first and only if false , b is also evaluated. Overloaded operators && and || don't have short-circuit optimisation (both a and b are always evaluated) and also the order of evaluation of the arguments is not specified.

  2. Comma operator The builtin version guarantees that the arguments are evaluated in the order they occur, ie in a,b a is evaluated first then b . With an overloaded comma operator, this guarantee is lost (and instead the function parameter mechanism comes into play).

  3. address-of operator There is a potential confusion between the builtin address-of operator & and the overloaded one when applied to objects of incomplete type. Consider this code

     struct type; // forward declaration: type is (as of yet) incomplete #include <memory> void foo(type &obj) // allowed: take object of incomplete type by reference { auto ptr1 = &obj; // address of obj -- or not? auto ptr2 = std::addressof(obj); // always address of obj } // possibly in a different translation unit: struct type { type* operator&() { return nullptr; } }; 

    This code exhibits unspecified behaviour : the compiler can implement either version of the & operator in foo() , but the human writing the code of foo() cannot know this or which operator will be used. This problem is avoided when using std::addressof as for ptr2 , which obtains the equivalent of the builtin address-of operator, even if type has an overloaded & operator.

If someone reads code and is seeing a if(a && b) , what will he/she think?
If a and b are native types like bool or int , everybody knows how it works.

If they are class objects, most people would expect that the class provides an operator bool() or similar to query what bool it should be, before applying && . Nobody will expect that it is a "fancy" way to write if(a.myMethod(b)) , and nobodywill check in the class definition => Everyone will misunderstand and/or be confused what purpose of the condition is.
tldr, don't use the builtin && as abbreviation for unrelated method calls.

The same is valid for || and , .

As for the address operator, in addition to the reading confusion issue, it's very present when writing code too: Pointer addresses normally can be acquired for any variable of any type, and no one will check your class definition before doing that.

Besides readability etc., if and in what order the arguments are evaluated differs:

For if(a&&b) normally, if a is false , b isn't even checked anymore, because the whole condition can only be false. If you have something like eg. if(a && func1()) func2(); where the return value of func2() matters, func1() is executed only if a is true , and only if both are true func2() is executed. With an overloaded && , func1() is always executed. Depending what it does, this may not be what you want.

With || , it's similar: If the first parameter is true , the second parameter normally isn't looked at anymore, because the whole condition is true anyways. With an overload, the parameter is always evaluated.

A normal comma operator a,b has the guarentee that a is evaluated/executed before b ; with an overload it can be in any order.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM