Difference between revisions of "cpp/language/operator logical"
m (link overloading) |
(see also logical_{and,or,not}) |
||
(11 intermediate revisions by 6 users not shown) | |||
Line 3: | Line 3: | ||
Returns the result of a boolean operation. | Returns the result of a boolean operation. | ||
− | {| class="wikitable" style="font-size:85%;" | + | {|class="wikitable" style="font-size:85%;" |
|- | |- | ||
− | ! rowspan="2" | Operator name | + | !rowspan="2"|Operator name |
− | ! rowspan="2" | Syntax | + | !rowspan="2"|Syntax |
− | ! rowspan="2" | {{rlp|operators|Over​load​able}} | + | !rowspan="2"|{{rlp|operators|Over​load​able}} |
− | ! colspan="2" | Prototype examples (for {{c|class T}}) | + | !colspan="2"|Prototype examples (for {{c|class T}}) |
|- | |- | ||
− | ! Inside class definition | + | !Inside class definition |
− | ! Outside class definition | + | !Outside class definition |
|- | |- | ||
− | | negation | + | |negation |
− | | {{c|not a}} | + | |{{c|not a}} |
− | {{ | + | {{c|1=!a}} |
− | | {{yes}} | + | |{{yes}} |
− | | {{c|bool T::operator!() const;}} | + | |{{c|bool T::operator!() const;}} |
− | | {{c|bool operator!(const T &a);}} | + | |{{c|bool operator!(const T &a);}} |
|- | |- | ||
− | | AND | + | |AND |
− | | {{c|a and b}} | + | |{{c|a and b}} |
− | {{ | + | {{c|a && b}} |
− | | {{yes}} | + | |{{yes}} |
− | | {{c|bool T::operator&&(const T2 &b) const;}} | + | |{{c|bool T::operator&&(const T2 &b) const;}} |
− | | {{c|bool operator&&(const T &a, const T2 &b);}} | + | |{{c|bool operator&&(const T &a, const T2 &b);}} |
|- | |- | ||
− | | inclusive OR | + | |inclusive OR |
− | | {{c|a or b}} | + | |{{c|a or b}} |
− | {{ | + | {{c|1=a {{!!}} b}} |
− | | {{yes}} | + | |{{yes}} |
− | | {{c|bool T::operator{{!!}}(const T2 &b) const;}} | + | |{{c|bool T::operator{{!!}}(const T2 &b) const;}} |
− | | {{c|bool operator{{!!}}(const T &a, const T2 &b);}} | + | |{{c|bool operator{{!!}}(const T &a, const T2 &b);}} |
|- | |- | ||
− | | colspan="5" | | + | |colspan="5" | |
:'''Notes'''<br> | :'''Notes'''<br> | ||
− | * The keyword-like forms ({{c|and}},{{c|or}},{{c|not}}) and the symbol-like forms ({{c|&&}},{{c|{{!!}}}},{{c|!}}) can be used interchangeably ( | + | * The keyword-like forms ({{c|and}},{{c|or}},{{c|not}}) and the symbol-like forms ({{c|&&}},{{c|{{!!}}}},{{c|!}}) can be used interchangeably (see {{rlp|operator_alternative|alternative representations}}). |
* All built-in operators return {{c|bool}}, and most {{rlp|operators|user-defined overloads}} also return {{c|bool}} so that the user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return type (including {{c|void}}). | * All built-in operators return {{c|bool}}, and most {{rlp|operators|user-defined overloads}} also return {{c|bool}} so that the user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return type (including {{c|void}}). | ||
− | * Builtin operators {{ttb|&&}} and {{ttb|{{!!}}}} perform short-circuit evaluation (do not evaluate the second operand if the result is known after evaluating the first), but overloaded operators behave like regular function calls and always evaluate both operands | + | * Builtin operators {{ttb|&&}} and {{ttb|{{!!}}}} perform short-circuit evaluation (do not evaluate the second operand if the result is known after evaluating the first), but overloaded operators behave like regular function calls and always evaluate both operands. |
|} | |} | ||
===Explanation=== | ===Explanation=== | ||
+ | The logic operator expressions have the form | ||
− | + | {{sdsc begin}} | |
+ | {{sdsc|num=1|{{ttb|!}} {{spar|rhs}}}} | ||
+ | {{sdsc|num=2|{{spar|lhs}} {{ttb|&&}} {{spar|rhs}}}} | ||
+ | {{sdsc|num=3|{{spar|lhs}} {{ttb|<nowiki>||</nowiki>}} {{spar|rhs}}}} | ||
+ | {{sdsc end}} | ||
+ | @1@ Logical NOT | ||
+ | @2@ Logical AND | ||
+ | @3@ Logical inclusive OR | ||
− | + | If the operand is not {{c|bool}}, it is converted to {{c|bool}} using {{rlp|implicit_conversion|contextual conversion to bool}}: it is only well-formed if the declaration {{tt|bool t(arg)}} is well-formed, for some invented temporary {{tt|t}}. | |
− | The | + | The result is a {{c|bool}} prvalue. |
− | {{ | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | For the built-in logical NOT operator, the result is {{c|true}} if the operand is {{c|false}}. Otherwise, the result is {{c|false}}. | |
− | For the built-in logical | + | For the built-in logical AND operator, the result is {{c|true}} if both operands are {{c|true}}. Otherwise, the result is {{c|false}}. This operator is {{enwiki|Short-circuit_evaluation|short-circuiting}}: if the first operand is {{c|false}}, the second operand is not evaluated. |
− | For the built-in logical | + | For the built-in logical OR operator, the result is {{c|true}} if either the first or the second operand (or both) is {{c|true}}. This operator is short-circuiting: if the first operand is {{c|true}}, the second operand is not evaluated. |
− | + | Note that {{rlp|operator_arithmetic|bitwise logic operators}} do not perform short-circuiting. | |
===Results=== | ===Results=== | ||
Line 104: | Line 107: | ||
|{{c|false}}<!--false||false--> | |{{c|false}}<!--false||false--> | ||
|} | |} | ||
+ | |||
+ | In {{rlp|overload_resolution#Call_to_an_overloaded_operator|overload resolution against user-defined operators}}, the following built-in function signatures participate in overload resolution: | ||
+ | {{dcl begin}} | ||
+ | {{dcl|bool operator!(bool)}} | ||
+ | {{dcl|bool operator&&(bool, bool)}} | ||
+ | {{dcl|bool operator{{!!}}(bool, bool)}} | ||
+ | {{dcl end}} | ||
===Example=== | ===Example=== | ||
{{example | {{example | ||
− | + | |code= | |
− | + | ||
#include <iostream> | #include <iostream> | ||
+ | #include <sstream> | ||
#include <string> | #include <string> | ||
+ | |||
int main() | int main() | ||
{ | { | ||
Line 116: | Line 127: | ||
int* p = &n; | int* p = &n; | ||
// pointers are convertible to bool | // pointers are convertible to bool | ||
− | if( p && *p == 2 | + | if ( p && *p == 2 // "*p" is safe to use after "p &&" |
− | + | {{!!}} !p && n != 2) // {{!!}} has lower precedence than && | |
std::cout << "true\n"; | std::cout << "true\n"; | ||
// streams are also convertible to bool | // streams are also convertible to bool | ||
+ | std::stringstream cin; | ||
+ | cin << "3...\n" << "2...\n" << "1...\n" << "quit"; | ||
std::cout << "Enter 'quit' to quit.\n"; | std::cout << "Enter 'quit' to quit.\n"; | ||
− | for(std::string line; std::cout << "> " | + | for (std::string line; std::cout << "> " |
− | + | && std::getline(cin, line) | |
− | + | && line != "quit";) | |
− | ; | + | std::cout << line << '\n'; |
} | } | ||
− | + | |output= | |
true | true | ||
Enter 'quit' to quit. | Enter 'quit' to quit. | ||
− | > | + | > 3... |
− | > | + | > 2... |
+ | > 1... | ||
+ | > | ||
}} | }} | ||
Line 138: | Line 153: | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc mem fun | cpp/numeric/valarray/operator_arith | title=operator! | applies a unary arithmetic operator to each element of the valarray}} | + | {{dsc mem fun|cpp/numeric/valarray/operator_arith|title=operator!|applies a unary arithmetic operator to each element of the valarray}} |
− | {{dsc tfun | cpp/numeric/valarray/operator_arith3 | title=operator&&<br>operator<nowiki>||</nowiki> | applies binary operators to each element of two valarrays, or a valarray and a value }} | + | {{dsc tfun|cpp/numeric/valarray/operator_arith3|title=operator&&<br>operator<nowiki>||</nowiki>|applies binary operators to each element of two valarrays, or a valarray and a value}} |
− | {{dsc inc | cpp/io/basic_ios/dsc operator!}} | + | {{dsc inc|cpp/io/basic_ios/dsc operator!}} |
{{dsc end}} | {{dsc end}} | ||
===See also=== | ===See also=== | ||
+ | {{rlp|operator precedence|Operator precedence}} | ||
− | + | {{rlp|operators|Operator overloading}} | |
− | + | {{dsc begin}} | |
+ | {{dsc inc | cpp/utility/functional/dsc logical_and}} | ||
+ | {{dsc inc | cpp/utility/functional/dsc logical_or}} | ||
+ | {{dsc inc | cpp/utility/functional/dsc logical_not}} | ||
+ | {{dsc end}} | ||
{{cpp/language/operators}} | {{cpp/language/operators}} | ||
+ | {{dsc begin}} | ||
+ | {{dsc see c|c/language/operator logical|Logical operators|nomono=true}} | ||
+ | {{dsc end}} | ||
− | + | {{langlinks|de|es|fr|it|ja|pt|ru|zh}} | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + |
Latest revision as of 04:30, 5 June 2024
Returns the result of a boolean operation.
Operator name | Syntax | Overloadable | Prototype examples (for class T) | |
---|---|---|---|---|
Inside class definition | Outside class definition | |||
negation | not a
!a |
Yes | bool T::operator!() const; | bool operator!(const T &a); |
AND | a and b
a && b |
Yes | bool T::operator&&(const T2 &b) const; | bool operator&&(const T &a, const T2 &b); |
inclusive OR | a or b
a || b |
Yes | bool T::operator||(const T2 &b) const; | bool operator||(const T &a, const T2 &b); |
|
Contents |
[edit] Explanation
The logic operator expressions have the form
! rhs
|
(1) | ||||||||
lhs && rhs
|
(2) | ||||||||
lhs || rhs
|
(3) | ||||||||
If the operand is not bool, it is converted to bool using contextual conversion to bool: it is only well-formed if the declaration bool t(arg)
is well-formed, for some invented temporary t
.
The result is a bool prvalue.
For the built-in logical NOT operator, the result is true if the operand is false. Otherwise, the result is false.
For the built-in logical AND operator, the result is true if both operands are true. Otherwise, the result is false. This operator is short-circuiting: if the first operand is false, the second operand is not evaluated.
For the built-in logical OR operator, the result is true if either the first or the second operand (or both) is true. This operator is short-circuiting: if the first operand is true, the second operand is not evaluated.
Note that bitwise logic operators do not perform short-circuiting.
[edit] Results
a | true | false |
---|---|---|
!a | false | true |
and | a | ||
---|---|---|---|
true | false | ||
b | true | true | false |
false | false | false |
or | a | ||
---|---|---|---|
true | false | ||
b | true | true | true |
false | true | false |
In overload resolution against user-defined operators, the following built-in function signatures participate in overload resolution:
bool operator!(bool) |
||
bool operator&&(bool, bool) |
||
bool operator||(bool, bool) |
||
[edit] Example
#include <iostream> #include <sstream> #include <string> int main() { int n = 2; int* p = &n; // pointers are convertible to bool if ( p && *p == 2 // "*p" is safe to use after "p &&" || !p && n != 2) // || has lower precedence than && std::cout << "true\n"; // streams are also convertible to bool std::stringstream cin; cin << "3...\n" << "2...\n" << "1...\n" << "quit"; std::cout << "Enter 'quit' to quit.\n"; for (std::string line; std::cout << "> " && std::getline(cin, line) && line != "quit";) std::cout << line << '\n'; }
Output:
true Enter 'quit' to quit. > 3... > 2... > 1... >
[edit] Standard library
Because the short-circuiting properties of operator&&
and operator||
do not apply to overloads, and because types with boolean semantics are uncommon, only two standard library classes overload these operators:
applies a unary arithmetic operator to each element of the valarray (public member function of std::valarray<T> )
| |
applies binary operators to each element of two valarrays, or a valarray and a value (function template) | |
checks if an error has occurred (synonym of fail()) (public member function of std::basic_ios<CharT,Traits> )
|
[edit] See also
function object implementing x && y (class template) | |
function object implementing x || y (class template) | |
function object implementing !x (class template) |
Common operators | ||||||
---|---|---|---|---|---|---|
assignment | increment decrement |
arithmetic | logical | comparison | member access |
other |
a = b |
++a |
+a |
!a |
a == b |
a[...] |
function call |
a(...) | ||||||
comma | ||||||
a, b | ||||||
conditional | ||||||
a ? b : c | ||||||
Special operators | ||||||
static_cast converts one type to another related type |
C documentation for Logical operators
|