A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://timsong-cpp.github.io/cppwp/n4659/over.oper below:

[over.oper]

16 Overloading [over] 16.5 Overloaded operators [over.oper]

Both the unary and binary forms of

+    -    *     &

can be overloaded.

The following operators cannot be overloaded:

.    .*   ::    ?:

nor can the preprocessing symbols # and ## (Clause [cpp]).

Operator functions are usually not called directly; instead they are invoked to evaluate the operators they implement ([over.unary][over.inc]). They can be explicitly called, however, using the operator-function-id as the name of the function in the function call syntax ([expr.call]). [Example:

complex z = a.operator+(b);     void* p = operator new(sizeof(int)*n);

end example]

The allocation and deallocation functions, operator new, operator new[], operator delete and operator delete​[], are described completely in [basic.stc.dynamic]. The attributes and restrictions found in the rest of this subclause do not apply to them unless explicitly stated in [basic.stc.dynamic].

An operator function shall either be a non-static member function or be a non-member function that has at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration. It is not possible to change the precedence, grouping, or number of operands of operators. The meaning of the operators =, (unary) &, and , (comma), predefined for each type, can be changed for specific class and enumeration types by defining operator functions that implement these operators. Operator functions are inherited in the same manner as other base class functions.

The identities among certain predefined operators applied to basic types (for example, ++a a+=1) need not hold for operator functions. Some predefined operators, such as +=, require an operand to be an lvalue when applied to basic types; this is not required by operator functions.

An operator function cannot have default arguments, except where explicitly stated below. Operator functions cannot have more or fewer parameters than the number required for the corresponding operator, as described in the rest of this subclause.

16.5.1 Unary operators [over.unary]

A prefix unary operator shall be implemented by a non-static member function ([class.mfct]) with no parameters or a non-member function with one parameter. Thus, for any prefix unary operator @, @x can be interpreted as either x.operator@() or operator@(x). If both forms of the operator function have been declared, the rules in [over.match.oper] determine which, if any, interpretation is used. See [over.inc] for an explanation of the postfix unary operators ++ and --.

The unary and binary forms of the same operator are considered to have the same name. [Note: Consequently, a unary operator can hide a binary operator from an enclosing scope, and vice versa. end note]

16.5.2 Binary operators [over.binary]

A binary operator shall be implemented either by a non-static member function ([class.mfct]) with one parameter or by a non-member function with two parameters. Thus, for any binary operator @, x@y can be interpreted as either x.operator@(y) or operator@(x,y). If both forms of the operator function have been declared, the rules in [over.match.oper] determine which, if any, interpretation is used.

16.5.3 Assignment [over.ass]

An assignment operator shall be implemented by a non-static member function with exactly one parameter. Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user ([class.copy]), a base class assignment operator is always hidden by the copy assignment operator of the derived class.

Any assignment operator, even the copy and move assignment operators, can be virtual. [Note: 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 override B's virtual copy/move assignment operator. [Example:

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);            *bptr = 99;                     bptr->operator=(dobj2);         *bptr = dobj2;                  dobj1 = dobj2;                }

end example] end note]

16.5.4 Function call [over.call]

operator() shall be a non-static member function with an arbitrary number of parameters. It can have default arguments. It implements the function call syntax

postfix-expression ( expression-listopt )

where the postfix-expression evaluates to a class object and the possibly empty expression-list matches the parameter list of an operator() member function of the class. Thus, a call x(arg1,...) is interpreted as x.operator()(arg1, ...) for a class object x of type T if T​::​operator()(T1, T2, T3) exists and if the operator is selected as the best match function by the overload resolution mechanism ([over.match.best]).

16.5.5 Subscripting [over.sub]

operator[] shall be a non-static member function with exactly one parameter. It implements the subscripting syntax

postfix-expression [ expr-or-braced-init-list ]

Thus, a subscripting expression x[y] is interpreted as x.operator[](y) for a class object x of type T if T​::​operator[](T1) exists and if the operator is selected as the best match function by the overload resolution mechanism ([over.match.best]). [Example:

struct X {
  Z operator[](std::initializer_list<int>);
};
X x;
x[{1,2,3}] = 7;           int a[10];
a[{1,2,3}] = 7;           

end example]

16.5.7 Increment and decrement [over.inc]

The user-defined function called operator++ implements the prefix and postfix ++ operator. If this function is a non-static member function with no parameters, or a non-member function with one parameter, it defines the prefix increment operator ++ for objects of that type. If the function is a non-static member function with one parameter (which shall be of type int) or a non-member function with two parameters (the second of which shall be of type int), it defines the postfix increment operator ++ for objects of that type. When the postfix increment is called as a result of using the ++ operator, the int argument will have value zero.134 [Example:

struct X {
  X&   operator++();              X    operator++(int);         };

struct Y { };
Y&   operator++(Y&);            Y    operator++(Y&, int);       
void f(X a, Y b) {
  ++a;                            a++;                            ++b;                            b++;                          
  a.operator++();                 a.operator++(0);                operator++(b);                  operator++(b, 0);             }

end example]

The prefix and postfix decrement operators -- are handled analogously.

16.5.8 User-defined literals [over.literal]
literal-operator-id:
	operator string-literal identifier
	operator user-defined-string-literal

The declaration of a literal operator shall have a parameter-declaration-clause equivalent to one of the following:

const char*
unsigned long long int
long double
char
wchar_t
char16_t
char32_t
const char*, std::size_t
const wchar_t*, std::size_t
const char16_t*, std::size_t
const char32_t*, std::size_t

If a parameter has a default argument, the program is ill-formed.

Literal operators and literal operator templates shall not have C language linkage.

[Note: Literal operators and literal operator templates are usually invoked implicitly through user-defined literals. However, except for the constraints described above, they are ordinary namespace-scope functions and function templates. In particular, they are looked up like ordinary functions and function templates and they follow the same overload resolution rules. Also, they can be declared inline or constexpr, they may have internal or external linkage, they can be called explicitly, their addresses can be taken, etc. end note]

[Example:

void operator "" _km(long double);                  string operator "" _i18n(const char*, std::size_t); template <char...> double operator "" _\u03C0();    float operator ""_e(const char*);                   float operator ""E(const char*);                    double operator""_Bq(long double);                  double operator"" _Bq(long double);                 float operator " " B(const char*);                  string operator "" 5X(const char*, std::size_t);    double operator "" _miles(double);                  template <char...> int operator "" _j(const char*); extern "C" void operator "" _m(long double);        

end example]


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4