Files
cppdraft_translate/cppdraft/over/oper.md
2025-10-25 03:02:53 +03:00

421 lines
21 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[over.oper]
# 12 Overloading [[over]](./#over)
## 12.4 Overloaded operators [over.oper]
### [12.4.1](#general) General [[over.oper.general]](over.oper.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3338)
A declaration
whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is an [*operator-function-id*](#nt:operator-function-id "12.4.1General[over.oper.general]") shall declare a function or function template or
an explicit instantiation or specialization of a function template[.](#general-1.sentence-1)
A function so declared is an [*operator function*](#def:function,operator "12.4.1General[over.oper.general]")[.](#general-1.sentence-2)
A function template so declared is
an [*operator function template*](#def:function,operator,template "12.4.1General[over.oper.general]")[.](#general-1.sentence-3)
A specialization of an operator function template is also an operator function[.](#general-1.sentence-4)
An operator function is said to[*implement*](#def:operator,implementation "12.4.1General[over.oper.general]") the operator named in its[*operator-function-id*](#nt:operator-function-id "12.4.1General[over.oper.general]")[.](#general-1.sentence-5)
[operator-function-id:](#nt:operator-function-id "12.4.1General[over.oper.general]")
operator [*operator*](#nt:operator "12.4.1General[over.oper.general]")
[operator:](#nt:operator "12.4.1General[over.oper.general]") one of
new delete new[] delete[] co_await ( ) [ ] -> ->*
~ ! + - * / % ^ &
| = += -= *= /= %= ^= &=
|= == != < > <= >= <=> &&
|| << >> <<= >>= ++ -- ,
[*Note [1](#general-note-1)*:
The operatorsnew[],delete[],(),
and[] are formed from more than one token[.](#general-1.sentence-6)
The latter two operators are [function call](expr.call "7.6.1.3Function call[expr.call]") and [subscripting](expr.sub "7.6.1.2Subscripting[expr.sub]")[.](#general-1.sentence-7)
— *end note*]
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3382)
Both the unary and binary forms of
+ - * &
can be overloaded[.](#general-2.sentence-1)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3389)
[*Note [2](#general-note-2)*:
The following operators cannot be overloaded:
. .* :: ?:
nor can the preprocessing symbols# ([[cpp.stringize]](cpp.stringize "15.7.3The # operator"))
and## ([[cpp.concat]](cpp.concat "15.7.4The ## operator"))[.](#general-3.sentence-1)
— *end note*]
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3402)
Operator functions are usually not called directly; instead they are invoked
to evaluate the operators they implement ([[over.unary]](#over.unary "12.4.2Unary operators") – [[over.inc]](#over.inc "12.4.7Increment and decrement"))[.](#general-4.sentence-1)
They can be explicitly called, however, using the[*operator-function-id*](#nt:operator-function-id "12.4.1General[over.oper.general]") as the name of the function in the function call syntax ([[expr.call]](expr.call "7.6.1.3Function call"))[.](#general-4.sentence-2)
[*Example [1](#general-example-1)*: complex z = a.operator+(b); // complex z = a+b;void* p = operator new(sizeof(int)*n); — *end example*]
[5](#general-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3416)
The allocation and deallocation functions,operator new,operator new[],operator delete, andoperator delete[],
are described completely in [[basic.stc.dynamic]](basic.stc.dynamic "6.8.6.5Dynamic storage duration")[.](#general-5.sentence-1)
The attributes and restrictions
found in the rest of [over.oper] do not apply to them unless explicitly
stated in [[basic.stc.dynamic]](basic.stc.dynamic "6.8.6.5Dynamic storage duration")[.](#general-5.sentence-2)
[6](#general-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3427)
The co_await operator is described completely in [[expr.await]](expr.await "7.6.2.4Await")[.](#general-6.sentence-1)
The attributes and restrictions
found in the rest of [over.oper] do not apply to it unless explicitly
stated in [[expr.await]](expr.await "7.6.2.4Await")[.](#general-6.sentence-2)
[7](#general-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3433)
An operator function
shall have at least one
function parameter or implicit object parameter whose type is
a class, a reference to a class, an
enumeration, or a reference to an enumeration[.](#general-7.sentence-1)
It is not possible to change the precedence, grouping, or number of operands
of operators[.](#general-7.sentence-2)
The meaning of
the operators =, (unary) &, and , (comma),
predefined for each type, can be changed for specific class types by
defining operator functions that implement these operators[.](#general-7.sentence-3)
Likewise, the meaning of the operators (unary) & and , (comma)
can be changed for specific enumeration types[.](#general-7.sentence-4)
Operator functions are inherited in the same manner as other base class
functions[.](#general-7.sentence-5)
[8](#general-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3452)
An operator function shall be a
prefix unary, binary, function call, subscripting, class member access, increment, or decrement
operator function[.](#general-8.sentence-1)
[9](#general-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3457)
[*Note [3](#general-note-3)*:
The identities among certain predefined operators applied to fundamental types
(for example,++a ≡a+=1)
need not hold for operator functions[.](#general-9.sentence-1)
Some predefined operators, such as+=,
require an operand to be an lvalue when applied to fundamental types;
this is not required by operator functions[.](#general-9.sentence-2)
— *end note*]
[10](#general-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3471)
An operator function cannot have [default arguments](dcl.fct.default "9.3.4.7Default arguments[dcl.fct.default]"),
except where explicitly stated below[.](#general-10.sentence-1)
Operator
functions cannot have more or fewer parameters than the
number required for the corresponding operator, as
described in the rest of [over.oper][.](#general-10.sentence-2)
[11](#general-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3480)
Operators not mentioned explicitly in subclauses [[over.assign]](#over.assign "12.4.3.2Simple assignment") through [[over.inc]](#over.inc "12.4.7Increment and decrement") act as ordinary unary and binary
operators obeying the rules of [[over.unary]](#over.unary "12.4.2Unary operators") or [[over.binary]](#over.binary "12.4.3Binary operators")[.](#general-11.sentence-1)
### [12.4.2](#over.unary) Unary operators [[over.unary]](over.unary)
[1](#over.unary-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3491)
A [*prefix unary operator function*](#def:operator_function,prefix_unary "12.4.2Unary operators[over.unary]") is a function named operator@ for a prefix [*unary-operator*](expr.unary.general#nt:unary-operator "7.6.2.1General[expr.unary.general]") @ ([[expr.unary.op]](expr.unary.op "7.6.2.2Unary operators"))
that is either
a non-static member function ([[class.mfct]](class.mfct "11.4.2Member functions")) with no non-object parameters or
a non-member function with one parameter[.](#over.unary-1.sentence-1)
For a [*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1General[expr.unary.general]") of the form @ [*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit type conversion (cast notation)[expr.cast]"),
the operator function is selected by overload resolution ([[over.match.oper]](over.match.oper "12.2.2.3Operators in expressions"))[.](#over.unary-1.sentence-2)
If a member function is selected,
the expression is interpreted as
[*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit type conversion (cast notation)[expr.cast]") . operator @ ()
Otherwise, if a non-member function is selected,
the expression is interpreted as
operator @ ( [*cast-expression*](expr.cast#nt:cast-expression "7.6.3Explicit type conversion (cast notation)[expr.cast]") )
[*Note [1](#over.unary-note-1)*:
The operators ++ and -- ([[expr.pre.incr]](expr.pre.incr "7.6.2.3Increment and decrement"))
are described in [[over.inc]](#over.inc "12.4.7Increment and decrement")[.](#over.unary-1.sentence-3)
— *end note*]
[2](#over.unary-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3517)
[*Note [2](#over.unary-note-2)*:
The unary and binary forms of the same operator have the same name[.](#over.unary-2.sentence-1)
Consequently, a unary operator can hide a binary
operator from an enclosing scope, and vice versa[.](#over.unary-2.sentence-2)
— *end note*]
### [12.4.3](#over.binary) Binary operators [[over.binary]](over.binary)
#### [12.4.3.1](#over.binary.general) General [[over.binary.general]](over.binary.general)
[1](#over.binary.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3530)
A [*binary operator function*](#def:operator_function,binary "12.4.3.1General[over.binary.general]") is a function named operator@ for a binary operator @ that is either
a non-static member function ([[class.mfct]](class.mfct "11.4.2Member functions")) with one non-object parameter or
a non-member function with two parameters[.](#over.binary.general-1.sentence-1)
For an expression x @ y with subexpressions x and y,
the operator function is selected by overload resolution ([[over.match.oper]](over.match.oper "12.2.2.3Operators in expressions"))[.](#over.binary.general-1.sentence-2)
If a member function is selected,
the expression is interpreted as
x . operator @ ( y )
Otherwise, if a non-member function is selected,
the expression is interpreted as
operator @ ( x , y )
[2](#over.binary.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3550)
An [*equality operator function*](#def:operator_function,equality "12.4.3.1General[over.binary.general]") is an operator function
for an equality operator ([[expr.eq]](expr.eq "7.6.10Equality operators"))[.](#over.binary.general-2.sentence-1)
A [*relational operator function*](#def:operator_function,relational "12.4.3.1General[over.binary.general]") is an operator function
for a relational operator ([[expr.rel]](expr.rel "7.6.9Relational operators"))[.](#over.binary.general-2.sentence-2)
A [*three-way comparison operator function*](#def:operator_function,three-way_comparison "12.4.3.1General[over.binary.general]") is an operator function
for the three-way comparison operator ([[expr.spaceship]](expr.spaceship "7.6.8Three-way comparison operator"))[.](#over.binary.general-2.sentence-3)
A [*comparison operator function*](#def:operator_function,comparison "12.4.3.1General[over.binary.general]") is
an equality operator function,
a relational operator function, or
a three-way comparison operator function[.](#over.binary.general-2.sentence-4)
#### [12.4.3.2](#over.assign) Simple assignment [[over.assign]](over.assign)
[1](#over.assign-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3566)
A [*simple assignment operator function*](#def:operator_function,simple_assignment "12.4.3.2Simple assignment[over.assign]") is a binary operator function named operator=[.](#over.assign-1.sentence-1)
A simple assignment operator function shall be a non-static member function[.](#over.assign-1.sentence-2)
[*Note [1](#over.assign-note-1)*:
Because only standard conversion sequences are considered when converting
to the left operand of an assignment operation ([[over.best.ics]](over.best.ics "12.2.4.2Implicit conversion sequences")),
an expression x = y with a subexpression x of class type
is always interpreted as x.operator=(y)[.](#over.assign-1.sentence-3)
— *end note*]
[2](#over.assign-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3577)
[*Note [2](#over.assign-note-2)*:
Since a copy assignment operator is implicitly declared for a class
if not declared by the user ([[class.copy.assign]](class.copy.assign "11.4.6Copy/move assignment operator")),
a base class assignment operator function is always hidden by
the copy assignment operator function of the derived class[.](#over.assign-2.sentence-1)
— *end note*]
[3](#over.assign-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3585)
[*Note [3](#over.assign-note-3)*:
Any assignment operator function, even the copy and move assignment operators,
can be virtual[.](#over.assign-3.sentence-1)
For a derived class D with a base class B for which a virtual copy/move assignment has been declared,
the copy/move assignment operator in D does not overrideB's virtual copy/move assignment operator[.](#over.assign-3.sentence-2)
[*Example [1](#over.assign-example-1)*: struct B {virtual int operator= (int); virtual B& operator= (const B&);};struct D : B {virtual int operator= (int); virtual D& operator= (const B&);};
D dobj1;
D dobj2;
B* bptr = &dobj1;void f() { bptr->operator=(99); // calls D::operator=(int)*bptr = 99; // ditto bptr->operator=(dobj2); // calls D::operator=(const B&)*bptr = dobj2; // ditto dobj1 = dobj2; // calls implicitly-declared D::operator=(const D&)} — *end example*]
— *end note*]
### [12.4.4](#over.call) Function call [[over.call]](over.call)
[1](#over.call-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3622)
A [*function call operator function*](#def:operator_function,function_call "12.4.4Function call[over.call]") is a function named operator() that is a member function with an arbitrary number of parameters[.](#over.call-1.sentence-1)
It may have default arguments[.](#over.call-1.sentence-2)
For an expression of the form
[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt )
where the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") is of class type,
the operator function
is selected by overload resolution ([[over.call.object]](over.call.object "12.2.2.2.3Call to object of class type"))[.](#over.call-1.sentence-3)
If a surrogate call function is selected,
let e be the result of invoking the corresponding conversion operator function on the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]");
the expression is interpreted as
e ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt )
Otherwise, the expression is interpreted as
[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") . operator () ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt )
### [12.4.5](#over.sub) Subscripting [[over.sub]](over.sub)
[1](#over.sub-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3650)
A [*subscripting operator function*](#def:operator_function,subscripting "12.4.5Subscripting[over.sub]") is a member function named operator[] with an arbitrary number of parameters[.](#over.sub-1.sentence-1)
It may have default arguments[.](#over.sub-1.sentence-2)
For an expression of the form
[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") [ [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt ]
the operator function
is selected by overload resolution ([[over.match.oper]](over.match.oper "12.2.2.3Operators in expressions"))[.](#over.sub-1.sentence-3)
If a member function is selected,
the expression is interpreted as
[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") . operator [] ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1General[expr.post.general]")opt )
[2](#over.sub-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3667)
[*Example [1](#over.sub-example-1)*: struct X { Z operator[](std::initializer_list<int>);
Z operator[](auto...);};
X x;
x[{1,2,3}] = 7; // OK, meaning x.operator[]({1,2,3}) x[1,2,3] = 7; // OK, meaning x.operator[](1,2,3)int a[10];
a[{1,2,3}] = 7; // error: built-in subscript operator a[1,2,3] = 7; // error: built-in subscript operator — *end example*]
### [12.4.6](#over.ref) Class member access [[over.ref]](over.ref)
[1](#over.ref-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3687)
A [*class member access operator function*](#def:operator_function,class_member_access "12.4.6Class member access[over.ref]") is a function named operator-> that is a non-static member function taking no non-object parameters[.](#over.ref-1.sentence-1)
For an expression of the form
[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") -> templateopt [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]")
the operator function
is selected by overload resolution ([[over.match.oper]](over.match.oper "12.2.2.3Operators in expressions")),
and the expression is interpreted as
( [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") . operator -> () ) -> templateopt [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]")
### [12.4.7](#over.inc) Increment and decrement [[over.inc]](over.inc)
[1](#over.inc-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3708)
An [*increment operator function*](#def:operator_function,increment "12.4.7Increment and decrement[over.inc]") is a function named operator++[.](#over.inc-1.sentence-1)
If this function is a non-static member function with no non-object parameters, or a non-member
function with one parameter,
it defines the prefix increment operator++ for objects of that type[.](#over.inc-1.sentence-2)
If the function is a non-static member function with one non-object parameter (which shall be of typeint)
or a non-member function with two parameters (the second of which shall be of typeint),
it defines the postfix increment operator++ for objects of that type[.](#over.inc-1.sentence-3)
When the postfix increment is called as a result of using the++ operator, theint argument will have value zero[.](#over.inc-1.sentence-4)[107](#footnote-107 "Calling operator++ explicitly, as in expressions like a.operator++(2), has no special properties: The argument to operator++ is 2.")
[*Example [1](#over.inc-example-1)*: struct X { X& operator++(); // prefix ++a X operator++(int); // postfix a++};
struct Y { };
Y& operator++(Y&); // prefix ++b Y operator++(Y&, int); // postfix b++void f(X a, Y b) {++a; // a.operator++(); a++; // a.operator++(0);++b; // operator++(b); b++; // operator++(b, 0); a.operator++(); // explicit call: like ++a; a.operator++(0); // explicit call: like a++;operator++(b); // explicit call: like ++b;operator++(b, 0); // explicit call: like b++;} — *end example*]
[2](#over.inc-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L3765)
A [*decrement operator function*](#def:operator_function,decrement "12.4.7Increment and decrement[over.inc]") is a function named operator-- and is handled analogously to an increment operator function[.](#over.inc-2.sentence-1)
[107)](#footnote-107)[107)](#footnoteref-107)
Callingoperator++ explicitly, as in expressions likea.operator++(2),
has no special properties:
The argument tooperator++ is2[.](#footnote-107.sentence-1)