Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/operator logical"

From cppreference.com
< cpp‎ | language
m (Shorten template names. Use {{lc}} where appropriate.)
(see also logical_{and,or,not})
 
(14 intermediate revisions by 7 users not shown)
Line 1: Line 1:
 
{{title|Logical operators}}
 
{{title|Logical operators}}
{{cpp/language/navbar}}
+
{{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" | Syntax
+
!rowspan="2"|Syntax
! rowspan="2" | Over&#8203;load&#8203;able
+
!rowspan="2"|{{rlp|operators|Over&#8203;load&#8203;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}}
{{tt|!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}}
{{tt|a&nbsp;&&&nbsp;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}}
{{tt|<nowiki>a&nbsp;||&nbsp;b</nowiki>}}
+
{{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 (See [[cpp/language/operator_alternative|alternative representations]])  
+
* 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 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
  
The logical operators apply logic functions (NOT, AND, and inclusive OR) to boolean arguments (or types contextually-convertible to {{c|bool}}), with a boolean result. Unlike the [[cpp/language/operator_arithmetic|bitwise logic operators]], these operators (in their built-in form) do not evaluate the second operand if the result is known after evaluating the first.
+
{{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
  
====Builtin operators====
+
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 following built-in function signatures participate in overload resolution:
+
The result is a {{c|bool}} prvalue.
{{dcl begin}}
+
{{dcl |bool operator!(bool)}}
+
{{dcl |bool operator&&(bool, bool)}}
+
{{dcl |bool operator{{!!}}(bool, bool)}}
+
{{dcl end}}
+
  
If the operand is not {{c|bool}}, it is converted to {{c|bool}} using [[cpp/language/implicit_cast|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}}.
+
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 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 AND operator, the result is {{c|true}} if both operands are {{c|true}}. Otherwise, the result is {{c|false}}. 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.
  
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}}. If the firstoperand 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=
| 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   // "*p" is safe to use after "p &&"
+
     if (    p && *p == 2 // "*p" is safe to use after "p &&"
      {{!!}} !p &&  n != 2 ) // {{!!}} has lower precedence than &&
+
        {{!!}} !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(std::cin, line)
+
                          && std::getline(cin, line)
                          && line != "quit"; )
+
                          && line != "quit";)
         ;
+
         std::cout << line << '\n';
 
}
 
}
| output=
+
|output=
 
true
 
true
 
Enter 'quit' to quit.
 
Enter 'quit' to quit.
> test
+
> 3...
> quit
+
> 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/dcl list 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/operator precedence | Operator precedence]]
 
 
{{cpp/language/operators}}
 
{{cpp/language/operators}}
 +
{{dsc begin}}
 +
{{dsc see c|c/language/operator logical|Logical operators|nomono=true}}
 +
{{dsc end}}
  
[[de:cpp/language/operator logical]]
+
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}
[[es:cpp/language/operator logical]]
+
[[fr:cpp/language/operator logical]]
+
[[it:cpp/language/operator logical]]
+
[[ja:cpp/language/operator logical]]
+
[[pt:cpp/language/operator logical]]
+
[[ru:cpp/language/operator logical]]
+
[[zh:cpp/language/operator logical]]
+

Latest revision as of 04:30, 5 June 2024

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Returns the result of a boolean operation.

Operator name Syntax Over​load​able 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);
Notes
  • The keyword-like forms (and,or,not) and the symbol-like forms (&&,||,!) can be used interchangeably (see alternative representations).
  • All built-in operators return bool, and most user-defined overloads also return 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 void).
  • Builtin operators && and || 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.

Contents

[edit] Explanation

The logic operator expressions have the form

! rhs (1)
lhs && rhs (2)
lhs || rhs (3)
1) Logical NOT
2) Logical AND
3) Logical inclusive OR

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]

[edit] See also

Operator precedence

Operator overloading

function object implementing x && y
(class template) [edit]
function object implementing x || y
(class template) [edit]
function object implementing !x
(class template) [edit]
Common operators
assignment increment
decrement
arithmetic logical comparison member
access
other

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b

a[...]
*a
&a
a->b
a.b
a->*b
a.*b

function call
a(...)
comma
a, b
conditional
a ? b : c
Special operators

static_cast converts one type to another related type
dynamic_cast converts within inheritance hierarchies
const_cast adds or removes cv-qualifiers
reinterpret_cast converts type to unrelated type
C-style cast converts one type to another by a mix of static_cast, const_cast, and reinterpret_cast
new creates objects with dynamic storage duration
delete destructs objects previously created by the new expression and releases obtained memory area
sizeof queries the size of a type
sizeof... queries the size of a parameter pack (since C++11)
typeid queries the type information of a type
noexcept checks if an expression can throw an exception (since C++11)
alignof queries alignment requirements of a type (since C++11)

C documentation for Logical operators