Namespaces
Variants

Other operators

From cppreference.com
 
 
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
 
 
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);
conditional operator a ? b : c No N/A N/A

The function call operator provides function semantics for any object.

The conditional operator (colloquially referred to as ternary conditional ) checks the boolean value of the first expression and, depending on the resulting value, evaluates and returns either the second or the third expression.

Built-in function call operator

Function call expressions have the following form:

function (arg1, arg2, arg3,...)
function - an expression function type or function pointer type
arg1, arg2, arg3,... - a possibly empty list of arbitrary expressions or brace-enclosed initializer lists(since C++11), except the comma operator is not allowed at the top level to avoid ambiguity

For a call to a non-member function or to a static member function, function can be an lvalue that refers to a function (in which case the function-to-pointer conversion is suppressed), or a prvalue of function pointer type.

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

If function 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.

Each function parameter is initialized with its corresponding argument after implicit conversion if necessary.

  • If there is no corresponding argument, the corresponding default argument is used, and if there is none, the program is ill-formed.
  • 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 full-expression where the function call appears, which means, for example, that if a constructor or destructor of a parameter throws an exception, the function try blocks of the called function are not considered.

If the function is a variadic function, default argument promotions are applied to all arguments matched by the ellipsis parameter.

It is implementation-defined whether a parameter is destroyed when the function in which it is defined exits or at the end of the enclosing full-expression. Parameters are always destroyed in the reverse order of their construction.

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 is 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 function specifies a destructor, the return type is void.

When an object of class type X is passed to or returned from a function, if each copy constructor, move constructor, and destructor of X is either trivial or deleted, and X has at least one non-deleted copy or move constructor, implementations are permitted to create a temporary object to hold the function parameter or result object.

The temporary object is constructed from the function argument or return value, respectively, and the function's parameter or return object is initialized as if by using the non-deleted trivial constructor to copy the temporary (even if that constructor is inaccessible or would not be selected by overload resolution to perform a copy or move of the object).

This allows objects of small class types, such as std::complex or std::span, to be passed to or returned from functions in registers.

(since C++17)

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 the operand of decltype (or as the right operand of a built-in comma operator that is the operand of decltype)(since C++11).

When the called function exits normally, all postcondition assertions of the function are evaluated in sequence. If the implementation introduces any temporary objects to hold the result value, for the evaluation E of each postcondition assertion:

(since C++26)

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.

#include <cstdio>

struct S
{
    int f1(double d)
    {
        return printf("%f \n", d); // variable argument function call
    }
    
    int f2()
    {
        return 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

Built-in comma operator

Comma expressions have the following form:

E1 , E2

In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded (although if it has class type, it won't be destroyed until the end of the containing full expression), and its side effects are completed before evaluation of the expression E2 begins (note that a user-defined operator, cannot guarantee sequencing)(until C++17).

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 expression(since C++17), the result of the expression is that temporary expression(since C++17). 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).

Using an unparenthesized comma expression as second (right) argument of a subscript operator is deprecated.

For example, a[b, c] is deprecated and a[(b, c)] is not.

(since C++20)
(until C++23)

An unparenthesized comma expression cannot be second (right) argument of a subscript operator. For example, a[b, c] is either ill-formed or equivalent to a.operator[](b, c).

Parentheses are needed when using a comma expression as the subscript, e.g., a[(b, c)].

(since C++23)
#include <iostream>

int main()
{
    // comma is often used to execute more than one expression
    // where the language grammar allows only one expression:
    
    // * in the third component of the for loop
    for (int i = 0, j = 10; i <= j; ++i, --j)
    //            ^list separator      ^comma operator
        std::cout << "i = " << i << " j = " << j << '\n';
    
    // * in a return statement
    // return log("an error!"), -1;
    
    // * in an initializer expression
    // MyClass(const Arg& arg)
    // : member{ throws_if_bad(arg), arg }
    
    // etc.
    
    // comma operators can be chained; the result of the last
    // (rightmost) expression is the result of the whole chain:
    int n = 1;
    int m = (++n, std::cout << "n = " << n << '\n', ++n, 2 * n);
    
    // m is now 6
    std::cout << "m = " << (++m, m) << '\n';
}

Output:

i = 0 j = 10
i = 1 j = 9
i = 2 j = 8
i = 3 j = 7
i = 4 j = 6
i = 5 j = 5
n = 2
m = 7

Conditional operator

The conditional operator expressions have the form

E1 ? E2 : E3

E1 is evaluated and contextually converted to bool, if the result is true, the result of the conditional expression is the value of E2 ; otherwise the result of the conditional expression is the value of E3 .

The type and value category of the conditional expression E1 ? E2 : E3 are determined as follows:

Stage 1

If both E2 and E3 are of type void, the result is an rvalue(until C++11)a prvalue(since C++11) of type void.

If exactly one of E2 and E3 is of type void:

  • If that operand of type void is be a (possibly parenthesized)