Other operators
Operator name | Syntax | Overloadable | 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); |
conversion | (type) a | Yes | operator type() | N/A |
ternary conditional | a ? b : c
|
No | N/A | N/A |
Contents |
[edit] Explanation
function call operator provides function semantics for any object.
conversion operator converts given type to another type. The name of the operator must be the same as the type intended to be returned.
ternary conditional operator checks the boolean value of the first expression and replaces entire operator clause with the second or the third expression depending on the resulting value.
[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
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.
#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 return value 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 return type and value category of the comma operator are exactly the return type and the value category of the second operand, E2
. If E2
is a temporary, the result of the comma operator is that temporary.
The comma in various comma-separated lists, such as function argument lists (f(a, b, c)), initializer lists int a[] = {1,2,3}, or initialization statements (int i, j;) is not the comma operator. If the comma operator needs to be used in that context, it has to be parenthesized: f(a, (n++, n+b), c)
Output:
n = 2 m = 7
[edit] Built-in conversion operator
The built-in conversion operator (T)expr evaluates the expression expr
and performs explicit cast to the type T
.
See explicit cast and user-defined conversion function for detailed description.
[edit] Conditional operator
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 overload resolution:
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 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.
In the conditional expression E1 ? E2 : E3, the following rules and limitations apply:
E2
or E3
is a throw-expression or another expression of type void, the result of the conditional operator is the result has the type and the value of the other (non-void) expression. If the non-void expression is a bit field, the result is a bit field. Such conditional operator is commonly used in C++11 constexpr programming.E2
or E3
are of type void, the result is a prvalue of type void.E2
and E3
have different class types (or same type with different cv-qualification) and the same value category. In this case, an attempt is made to convert one (and only one) of the operands to the type of the other, as follows:E2
or E3
are glvalues of the same type. In this case, the result has the same type and value category.E2
or E3
has class type: overload resolution is attempted to select the best conversion from one type to the other.E2
nor E3
have class type: first, lvalue-to-rvalue, array-to-pointer, and function-to-pointer conversions are applied. Then, E2
and E3
now have the same type, the result is a prvalue temporary of that type, copy-initialized from whatever operand was selected after evaluating E1
E2
and E3
have arithmetic or enumeration type: usual arithmetic conversions are applied to bring them to common type, that type is the result.E2
and E3
are pointers, or a pointer and a null constant, or a both null pointer constants, one of which is a std::nullptr_t, then pointer conversions and qualification conversions are applied to bring them to common type, that type is the result.E2
and E3
are pointers to members, or a pointer to member and a null constant: then pointer-to-member conversions and qualification conversions are applied to bring them to common type, that type is the result.The return type of a conditional operator is also accessible as the binary type trait std::common_type
#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 override operator()
to be used as function objects.
deletes the object or array (public member function of std::default_delete )
|
|
returns the sum of two arguments (public member function of std::plus )
|
|
returns the difference between two arguments (public member function of std::minus )
|
|
returns the product of two arguments (public member function of std::multiplies )
|
|
returns the result of the division of the first argument by the second argument (public member function of std::divides )
|
|
returns the remainder from the division of the first argument by the second argument (public member function of std::modulus )
|
|
returns the negation of the argument (public member function of std::negate )
|
|
checks if the arguments are equal (public member function of std::equal_to )
|
|
checks if the arguments are not equal (public member function of std::not_equal_to )
|
|
checks if the first argument is greater than the second (public member function of std::greater )
|
|
checks if the first argument is less than the second (public member function of std::less )
|
|
checks if the first argument is greater than or equal to the second (public member function of std::greater_equal )
|
|
checks if the first argument is less than or equal to the second (public member function of std::less_equal )
|
|
returns the logical AND of the two arguments (public member function of std::logical_and )
|
|
returns the logical OR of the two arguments (public member function of std::logical_or )
|
|
returns the logical NOT of the argument (public member function of std::logical_not )
|
|
returns the result of bitwise AND of two arguments (public member function of std::bit_and )
|
|
returns the result of bitwise OR of two arguments (public member function of std::bit_or )
|
|
returns the result of bitwise XOR of two arguments (public member function of std::bit_xor )
|
|
returns the logical complement of the result of a call to the stored predicate (public member function of std::unary_negate )
|
|
returns the logical complement of the result of a call to the stored predicate (public member function of std::binary_negate )
|
|
calls the stored function (public member function of std::reference_wrapper )
|
|
invokes the target (public member function of std::function )
|
|
lexicographically compares two strings using this locale's collate facet (public member function of std::locale )
|
|
compares two values of type value_type (public member function of std::map::value_compare )
|
|
compares two values of type value_type (public member function of std::multimap::value_compare )
|
|
executes the function (public member function of std::packaged_task )
|
|
advances the engine's state and returns the generated value (public member function of std::linear_congruential_engine )
|
|
generates the next random number in the distribution (public member function of std::uniform_int_distribution )
|
Several standard library classes provide user-defined conversion functions
checks if the value is non-zero (public member function of std::error_code )
|
|
checks if the value is non-zero (public member function of std::error_condition )
|
|
returns the referenced bit (public member function of std::bitset::reference )
|
|
returns the referenced bit (public member function of std::vector<bool>::reference )
|
|
checks if there is associated managed object (public member function of std::unique_ptr )
|
|
checks if there is associated managed object (public member function of std::shared_ptr )
|
|
accesses the stored reference (public member function of std::reference_wrapper )
|
|
checks if a valid target is contained (public member function of std::function )
|
|
returns the wrapped value (public member function of std::integral_constant )
|
|
(until C++11)(since C++11)
|
checks if no error has occurred (synonym of !fail()) (public member function of std::basic_ios )
|
converts to the underlying string type (public member function of std::sub_match )
|
|
loads a value from an atomic object (public member function of std::atomic )
|
|
tests whether the lock owns its associated mutex (public member function of std::unique_lock )
|
|
converts the managed pointer to a pointer to different type (public member function of std::auto_ptr )
|
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
Common operators | ||||||
---|---|---|---|---|---|---|
assignment | increment decrement |
arithmetic | logical | comparison | member access |
other |
a = b |
++a |
+a |
!a |
a == b |
a[b] |
a(...) |
Special operators | ||||||
static_cast converts one type to another compatible type |