Other operators - cppreference.com

##### cppreference.com

##### Search

Create account

##### Namespaces

- Page
- Discussion

##### Variants

##### Views

- View
- Edit
- History

##### Actions

# Other operators

From cppreference.com
< cpp‎ | language

Operator name | Syntax | Over​load​able | Prototype examples (for class T)
--- | --- | --- | ---
Inside class definition | Outside class definition
function call | `a(a1, a2)` | Yes | R T::operator()(Arg1 &a1, Arg2 &a2, ... ...); | N/A
comma | `a, b` | Yes | T2& T::operator,(T2 &b); | T2& operator,(const T &a, T2 &b);
ternary conditional | `a ? b : c` | No | N/A | N/A

### [edit] Explanation

The function call operator provides function semantics for any object.

The ternary conditional operator checks the boolean value of the first expression and, depending on the resulting value, evaluates and returns either the second or the third expression.

#### [edit] Built-in function call operator

A function call expression, such as E(A1, A2, A3), consists of an expression that names the function, `E`, followed by a possibly empty list of expressions `A1, A2, A3, ...`, in parentheses.

The expression that names the function can be

a) lvalue expression that refers to a function
b) pointer to function
c) explicit class member access expression that selects a member function
d) implicit class member access expression, e.g. member function name used within another member function.

The function (or member) name specified by `E` can be overloaded, overload resolution rules used to decide which overload is to be called.

If `E` specifies a member function, it may be virtual, in which case the final overrider of that function will be called, using dynamic dispatch at runtime.

To call the function, all expressions `A1`, `A2`, `A3`, etc, provided as arguments are evaluated in arbitrary order, and each function parameter is initialized with its corresponding argument after implicit conversion if neccessary. If the call is made to a member function, then the this pointer to current object is converted as if by explicit cast to the this pointer expected by the function. The initialization and destruction of each parameter occurs in the context of the caller, which means, for example, that if constructor of a parameter throws an exception, the exception handlers defined within the function, even as a function-try block, are not considered. If the function is a variadic function, default argument promotions are applied to all arguments matched by the ellipsis parameter.

The return type of a function call expression is the return type of the chosen function, decided using static binding (ignoring the `virtual` keyword), even if the overriding function that's actually called returns a different type. This allows the overriding functions to return pointers or references to classes that are derived from the return type returned by the base function, i.e. C++ supports covariant return types. If `E` specifies a destructor, the return type is void.

The value category of a function call expression is lvalue if the function returns an lvalue reference or an rvalue reference to function, is an xvalue if the function returns an rvalue reference to object, and is a prvalue otherwise. If the function call expression is a prvalue of object type, it must have complete type except when used as an operand to decltype.

Function call expression is similar in syntax to value initialization T(), to function-style cast expression T(A1), and to direct initialization of a temporary T(A1, A2, A3, ...), where `T` is the name of a type.

Run this code

    #include <cstdio>
    struct S
    {
        int f1(double d) {
            printf("%f \n", d); // variable argument function call
        }
        int f2() {
            f1(7); // member function call, same as this->f1()
                   // integer argument converted to double
        }
    };
    void f() {
       puts("function called"); // function call
    }
    int main()
    {
        f(); // function call
        S s;
        s.f2(); // member function call
    }

Output:

    function called
    7.000000

#### [edit] Built-in comma operator

In a comma expression E1, E2, the expression `E1` is evaluated, its result is discarded, and its side effects are completed before evaluation of the expression `E2` begins (note that a user-defined `operator,` cannot guarantee sequencing).

The type, value, and value category of the result of the comma expression are exactly the type, value, and value category of the second operand, `E2`. If `E2` is a temporary, the result of the expression is that temporary. If `E2` is a bit-field, the result is a bit-field.

The comma in various comma-separated lists, such as function argument lists (f(a, b, c)) and initializer lists int a[] = {1,2,3}, is not the comma operator. If the comma operator needs to be used in such contexts, it has to be parenthesized: f(a, (n++, n+b), c)

Run this code

    #include <iostream>
    int main()
    {
        int n = 1;
        int m = (++n, std::cout << "n = " << n << '\n', ++n, 2*n);
        std::cout << "m = " << (++m, m) << '\n';
    }

Output:

    n = 2
    m = 7

#### [edit] Conditional operator

The first operand of the conditional operator is evaluated and contextually converted to bool. After both the value evaluation and all side effects of the first operand are completed, if the result was true, the second operand is evaluated. If the result was false, the third operand is evaluated.

The type and value category of the conditional expression E1 ? E2 : E3 are determined according to the following rules:

1. If either `E2` or `E3` has type void, one of the following must be true, or the program is ill-formed:
   - Either `E2` or `E3` (but not both) is a (possibly parenthesized) throw-expression. The result of the conditional operator has the type and the value category of the other expression. If the other expression is a bit field, the result is a bit field. Such conditional operator is commonly used in C++11 constexpr programming.
   - Both `E2` and `E3` are of type void (including the case when they are both throw-expressions). The result is a prvalue of type void.
2. Otherwise, if `E2` and `E3` have different types, at least one of which is a (possibly cv-qualified) class type, or both are glvalues of the same value category and have the same type except for cv-qualification, then an attempt is made to convert one of the operands to match the type of the other, as described below. If both operands can be converted, or if only one can be converted but the conversion is ambiguous, the program is ill-formed. If no conversion can be performed, the operands are left unchanged. If only one operand can be converted, the conversion is applied and the converted operand is used in place of the original operand. In both cases, further analysis is then performed starting from step 3.

   An operand (call it `S`) of type `TS` can be converted to match the other operand (call it `T`) of type `TT` as follows:

   - If `T` is an lvalue, an implicit conversion to the type `TT&` is attempted, provided that the reference must bind directly for the conversion to succeed;
   - If `T` is an xvalue, an implicit conversion to the type `TT&&` is attempted, provided that the reference must bind directly for the conversion to succeed;
   - If `T` is an prvalue, or if neither the above conversions can be done and at least one of `TS` and `TT` is a (possibly cv-qualified) class type:
     - If both `S` and `T` have class type, and the underlying class types are the same class or one is a base class of another, then `S` can be converted to match `T` if the class of `TT` is the same type as, or a base class of, the class of `TS` and the cv-qualification of `TT` is the same as or greater than that of `TS`. The conversion changes `S` into a prvalue of type `TT` by by copy-initializing a temporary object of the base type.
     - Otherwise, an implicit conversion is attempted to the type `T` would have after applying the lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions.
3. If `E2` and `E3` are glvalues of the same type and the same value category, then the result has the same type and value category, and is a bit-field if at least one of `E2` and `E3` is a bit-field.
4. Otherwise, the result is a prvalue. If `E2` and `E3` do not have the same type, and either has (possibly cv-qualified) class type, overload resolution is performed using the built-in candidates below to attempt to convert the operands to built-in types. If the overload resolution fails, the program is ill-formed. Otherwise, the selected conversions are applied and the converted operands are used in place of the original operands for step 5.
5. The lvalue-to-rvalue, array-to-pointer, and function-to-pointer conversions are applied to the second and third operands. Then,
   - If both `E2` and `E3` now have the same type, the result is of that type. If that type is a class type, the result is a prvalue temporary of that type, copy-initialized from whatever operand was selected after evaluating `E1`.
   - If both `E2` and `E3` have arithmetic or enumeration type: the usual arithmetic conversions are applied to bring them to common type, and that type is the result.
   - If both `E2` and `E3` are pointers, or one is a pointer and the other is a null pointer constant, then pointer conversions and qualification conversions are applied to bring them to common type, and that type is the result.
   - If both `E2` and `E3` are pointers to members, or one is a pointer to member and the other is a null pointer constant, then pointer-to-member conversions and qualification conversions are applied to bring them to common type, and that type is the result.
   - If both `E2` and `E3` are null pointer constants, and at least one of which is of type std::nullptr_t, then the result's type is `std::nullptr_t`.
   - In all other cases, the program is ill-formed.

For every pair of promoted arithmetic types L and R and for every type P, where P is a pointer, pointer-to-member, or scoped enumeration type, the following function signatures participate in the overload resolution performed in step 4 of the rules above:

LR operator?:(bool, L, R ); |  |
P operator?:(bool, P, P ); |  |

where LR is the result of usual arithmetic conversions performed on `L` and `R`. The operator “?:” cannot be overloaded, these function signatures only exist for the purpose of overload resolution.

The return type of a conditional operator is also accessible as the binary type trait std::common_type.

Run this code

    #include <string>
    #include <stdexcept>
    struct Node
    {
        Node* next;
        int data;
        // deep-copying copy constructor
        Node(const Node& other)
          : next(other.next ? new Node(*other.next) : NULL)
          , data(other.data)
        {}
        Node(int d) : next(NULL), data(d) {}
        ~Node() { delete next ; }
    };
    int main()
    {
        // simple rvalue example
        int n = 1>2 ? 10 : 11;  // 1>2 is false, so n = 11
        // simple lvalue example
        int m = 10;
        (n == m ? n : m) = 7; // n == m is false, so m = 7
        // throw example
        std::string str = 2+2==4 ? "ok" : throw std::logic_error("2+2 != 4");
    }

### [edit] Standard library

Many classes in the standard library overload `operator()` to be used as function objects.

operator() | deletes the object or array (public member function of `std::default_delete`) [edit]
operator() | returns the sum of two arguments (public member function of `std::plus`) [edit]
operator() | returns the difference between two arguments (public member function of `std::minus`) [edit]
operator() | returns the product of two arguments (public member function of `std::multiplies`) [edit]
operator() | returns the result of the division of the first argument by the second argument (public member function of `std::divides`) [edit]
operator() | returns the remainder from the division of the first argument by the second argument (public member function of `std::modulus`) [edit]
operator() | returns the negation of the argument (public member function of `std::negate`) [edit]
operator() | checks if the arguments are equal (public member function of `std::equal_to`) [edit]
operator() | checks if the arguments are not equal (public member function of `std::not_equal_to`) [edit]
operator() | checks if the first argument is greater than the second (public member function of `std::greater`) [edit]
operator() | checks if the first argument is less than the second (public member function of `std::less`) [edit]
operator() | checks if the first argument is greater than or equal to the second (public member function of `std::greater_equal`) [edit]
operator() | checks if the first argument is less than or equal to the second (public member function of `std::less_equal`) [edit]
operator() | returns the logical AND of the two arguments (public member function of `std::logical_and`) [edit]
operator() | returns the logical OR of the two arguments (public member function of `std::logical_or`) [edit]
operator() | returns the logical NOT of the argument (public member function of `std::logical_not`) [edit]
operator() | returns the result of bitwise AND of two arguments (public member function of `std::bit_and`) [edit]
operator() | returns the result of bitwise OR of two arguments (public member function of `std::bit_or`) [edit]
operator() | returns the result of bitwise XOR of two arguments (public member function of `std::bit_xor`) [edit]
operator() | returns the logical complement of the result of a call to the stored predicate (public member function of `std::unary_negate`) [edit]
operator() | returns the logical complement of the result of a call to the stored predicate (public member function of `std::binary_negate`) [edit]
operator() | calls the stored function (public member function of `std::reference_wrapper`) [edit]
operator() | invokes the target (public member function of `std::function`) [edit]
operator() | lexicographically compares two strings using this locale's collate facet (public member function of `std::locale`) [edit]
operator() | compares two values of type `value_type` (public member function of `std::map::value_compare`) [edit]
operator() | compares two values of type `value_type` (public member function of `std::multimap::value_compare`) [edit]
operator() | executes the function (public member function of `std::packaged_task`) [edit]
operator() | advances the engine's state and returns the generated value (public member function of `std::linear_congruential_engine`) [edit]
operator() | generates the next random number in the distribution (public member function of `std::uniform_int_distribution`) [edit]

The comma operator is not overloaded by any class in the standard library. The boost library uses `operator,` in boost.assign, boost.spirit, and other libraries. The database access library SOCI also overloads `operator,`.

### [edit] See also

Operator precedence

Operator overloading

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->b a.b a->*b a.*b | a(...) a, b ? :
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` allocates memory `delete` deallocates memory `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)

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=cpp/language/operator_other&oldid=81290"