Difference between revisions of "cpp/language/operator logical"
(misc fixes) |
(see also logical_{and,or,not}) |
||
(20 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
{{title|Logical operators}} | {{title|Logical operators}} | ||
− | {{cpp/language/ | + | {{cpp/language/expressions/navbar}} |
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" | | + | !rowspan="2"|Syntax |
− | ! rowspan="2" | | + | !rowspan="2"|{{rlp|operators|Over​load​able}} |
− | + | !colspan="2"|Prototype examples (for {{c|class T}}) | |
− | ! colspan="2" | Prototype examples (for {{ | + | |
|- | |- | ||
− | ! Inside class definition | + | !Inside class definition |
− | ! Outside class definition | + | !Outside class definition |
|- | |- | ||
− | | negation | + | |negation |
− | | {{ | + | |{{c|not a}} |
− | + | {{c|1=!a}} | |
− | | {{yes}} | + | |{{yes}} |
− | | {{ | + | |{{c|bool T::operator!() const;}} |
− | | {{ | + | |{{c|bool operator!(const T &a);}} |
|- | |- | ||
− | | AND | + | |AND |
− | | {{ | + | |{{c|a and b}} |
− | + | {{c|a && b}} | |
− | | {{yes}} | + | |{{yes}} |
− | | {{ | + | |{{c|bool T::operator&&(const T2 &b) const;}} |
− | | {{ | + | |{{c|bool operator&&(const T &a, const T2 &b);}} |
|- | |- | ||
− | | inclusive OR | + | |inclusive OR |
− | | {{ | + | |{{c|a or b}} |
− | + | {{c|1=a {{!!}} b}} | |
− | | {{yes}} | + | |{{yes}} |
− | | {{ | + | |{{c|bool T::operator{{!!}}(const T2 &b) const;}} |
− | | {{ | + | |{{c|bool operator{{!!}}(const T &a, const T2 &b);}} |
|- | |- | ||
− | | colspan=" | + | |colspan="5" | |
:'''Notes'''<br> | :'''Notes'''<br> | ||
− | * The keyword-like forms ({{ | + | * 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}}). |
+ | * 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=== | ||
+ | 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 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 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 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=== | ||
{|table class=wikitable | {|table class=wikitable | ||
− | !{{ | + | !{{c|a}} |
− | |{{ | + | |{{c|true}} |
− | |{{ | + | |{{c|false}} |
|- | |- | ||
− | !{{ | + | !{{c|!a}} |
− | |{{ | + | |{{c|false}} |
− | |{{ | + | |{{c|true}} |
|} | |} | ||
{|table class=wikitable | {|table class=wikitable | ||
− | !colspan=2 rowspan=2|{{ | + | !colspan=2 rowspan=2|{{c|and}} |
− | !colspan=2|{{ | + | !colspan=2|{{c|a}} |
|- | |- | ||
− | |{{ | + | |{{c|true}} <!--a--> |
− | |{{ | + | |{{c|false}} <!--a--> |
|- | |- | ||
− | !rowspan=2|{{ | + | !rowspan=2|{{c|b}} |
− | |{{ | + | |{{c|true}} <!--b--> |
− | |{{ | + | |{{c|true}} <!--true&&true--> |
− | |{{ | + | |{{c|false}}<!--true&&false--> |
|- | |- | ||
− | |{{ | + | |{{c|false}}<!--b--> |
− | |{{ | + | |{{c|false}}<!--true&&false--> |
− | |{{ | + | |{{c|false}}<!--false&&false--> |
|} | |} | ||
{|table class=wikitable | {|table class=wikitable | ||
− | !colspan=2 rowspan=2|{{ | + | !colspan=2 rowspan=2|{{c|or}} |
− | !colspan=2|{{ | + | !colspan=2|{{c|a}} |
|- | |- | ||
− | |{{ | + | |{{c|true}} <!--a--> |
− | |{{ | + | |{{c|false}}<!--a--> |
|- | |- | ||
− | !rowspan=2|{{ | + | !rowspan=2|{{c|b}} |
− | |{{ | + | |{{c|true}}<!--b--> |
− | |{{ | + | |{{c|true}}<!--true||true--> |
− | |{{ | + | |{{c|true}}<!--true||false--> |
|- | |- | ||
− | |{{ | + | |{{c|false}}<!--b--> |
− | |{{ | + | |{{c|true}}<!--false||true--> |
− | |{{ | + | |{{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 | ||
+ | |code= | ||
+ | #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... | ||
+ | > | ||
+ | }} | ||
+ | |||
+ | ===Standard library=== | ||
+ | Because the short-circuiting properties of {{tt|operator&&}} and {{tt|operator{{!!}}}} do not apply to overloads, and because types with boolean semantics are uncommon, only two standard library classes overload these operators: | ||
+ | |||
+ | {{dsc begin}} | ||
+ | {{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 inc|cpp/io/basic_ios/dsc operator!}} | ||
+ | {{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
|