cppreference.com

Assignment operators.

(C++20)
(C++20)
(C++11)
(C++20)
(C++17)
(C++11)
(C++11)
General topics
(C++11)
-
-expression
block


/
(C++11)
(C++11)
(C++11)
(C++20)
(C++20)
(C++11)

expression
pointer
specifier

specifier (C++11)
specifier (C++11)
(C++11)

(C++11)
(C++11)
(C++11)
General
(C++11)
(C++26)

(C++11)
(C++11)
-expression
-expression
-expression
(C++11)
(C++11)
(C++17)
(C++20)
    

Assignment operators modify the value of the object.

Operator name  Syntax  Prototype examples (for class T)
Inside class definition Outside class definition
simple assignment Yes T& T::operator =(const T2& b);
addition assignment Yes T& T::operator +=(const T2& b); T& operator +=(T& a, const T2& b);
subtraction assignment Yes T& T::operator -=(const T2& b); T& operator -=(T& a, const T2& b);
multiplication assignment Yes T& T::operator *=(const T2& b); T& operator *=(T& a, const T2& b);
division assignment Yes T& T::operator /=(const T2& b); T& operator /=(T& a, const T2& b);
remainder assignment Yes T& T::operator %=(const T2& b); T& operator %=(T& a, const T2& b);
bitwise AND assignment Yes T& T::operator &=(const T2& b); T& operator &=(T& a, const T2& b);
bitwise OR assignment Yes T& T::operator |=(const T2& b); T& operator |=(T& a, const T2& b);
bitwise XOR assignment Yes T& T::operator ^=(const T2& b); T& operator ^=(T& a, const T2& b);
bitwise left shift assignment Yes T& T::operator <<=(const T2& b); T& operator <<=(T& a, const T2& b);
bitwise right shift assignment Yes T& T::operator >>=(const T2& b); T& operator >>=(T& a, const T2& b);

this, and most also return *this so that the user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return type (including void). can be any type including .
Definitions Assignment operator syntax Built-in simple assignment operator Assignment from an expression Assignment from a non-expression initializer clause Built-in compound assignment operator Example Defect reports See also

[ edit ] Definitions

Copy assignment replaces the contents of the object a with a copy of the contents of b ( b is not modified). For class types, this is performed in a special member function, described in copy assignment operator .

replaces the contents of the object a with the contents of b, avoiding copying if possible (b may be modified). For class types, this is performed in a special member function, described in .

(since C++11)

For non-class types, copy and move assignment are indistinguishable and are referred to as direct assignment .

Compound assignment replace the contents of the object a with the result of a binary operation between the previous value of a and the value of b .

[ edit ] Assignment operator syntax

The assignment expressions have the form

target-expr new-value (1)
target-expr op new-value (2)
target-expr - the expression to be assigned to
op - one of *=, /= %=, += -=, <<=, >>=, &=, ^=, |=
new-value - the expression (until C++11) (since C++11) to assign to the target
  • ↑ target-expr must have higher precedence than an assignment expression.
  • ↑ new-value cannot be a comma expression, because its precedence is lower.

If new-value is not an expression, the assignment expression will never match an overloaded compound assignment operator.

(since C++11)

[ edit ] Built-in simple assignment operator

For the built-in simple assignment, the object referred to by target-expr is modified by replacing its value with the result of new-value . target-expr must be a modifiable lvalue.

The result of a built-in simple assignment is an lvalue of the type of target-expr , referring to target-expr . If target-expr is a bit-field , the result is also a bit-field.

[ edit ] Assignment from an expression

If new-value is an expression, it is implicitly converted to the cv-unqualified type of target-expr . When target-expr is a bit-field that cannot represent the value of the expression, the resulting value of the bit-field is implementation-defined.

If target-expr and new-value identify overlapping objects, the behavior is undefined (unless the overlap is exact and the type is the same).

If the type of target-expr is volatile-qualified, the assignment is deprecated, unless the (possibly parenthesized) assignment expression is a or an .

(since C++20)

new-value is only allowed not to be an expression in following situations:

is of a , and new-value is empty or has only one element. In this case, given an invented variable t declared and initialized as T t = new-value , the meaning of x = new-value  is x = t. is of class type. In this case, new-value is passed as the argument to the assignment operator function selected by .   <double> z; z = {1, 2}; // meaning z.operator=({1, 2}) z += {1, 2}; // meaning z.operator+=({1, 2})   int a, b; a = b = {1}; // meaning a = b = 1; a = {1} = b; // syntax error
(since C++11)

In overload resolution against user-defined operators , for every type T , the following function signatures participate in overload resolution:

& operator=(T*&, T*);
volatile & operator=(T*volatile &, T*);

For every enumeration or pointer to member type T , optionally volatile-qualified, the following function signature participates in overload resolution:

operator=(T&, T);

For every pair A1 and A2 , where A1 is an arithmetic type (optionally volatile-qualified) and A2 is a promoted arithmetic type, the following function signature participates in overload resolution:

operator=(A1&, A2);

[ edit ] Built-in compound assignment operator

The behavior of every built-in compound-assignment expression target-expr   op   =   new-value is exactly the same as the behavior of the expression target-expr   =   target-expr   op   new-value , except that target-expr is evaluated only once.

The requirements on target-expr and new-value of built-in simple assignment operators also apply. Furthermore:

  • For + = and - = , the type of target-expr must be an arithmetic type or a pointer to a (possibly cv-qualified) completely-defined object type .
  • For all other compound assignment operators, the type of target-expr must be an arithmetic type.

In overload resolution against user-defined operators , for every pair A1 and A2 , where A1 is an arithmetic type (optionally volatile-qualified) and A2 is a promoted arithmetic type, the following function signatures participate in overload resolution:

operator*=(A1&, A2);
operator/=(A1&, A2);
operator+=(A1&, A2);
operator-=(A1&, A2);

For every pair I1 and I2 , where I1 is an integral type (optionally volatile-qualified) and I2 is a promoted integral type, the following function signatures participate in overload resolution:

operator%=(I1&, I2);
operator<<=(I1&, I2);
operator>>=(I1&, I2);
operator&=(I1&, I2);
operator^=(I1&, I2);
operator|=(I1&, I2);

For every optionally cv-qualified object type T , the following function signatures participate in overload resolution:

& operator+=(T*&, );
& operator-=(T*&, );
volatile & operator+=(T*volatile &, );
volatile & operator-=(T*volatile &, );

[ edit ] Example

Possible output:

[ edit ] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
C++11 for assignments to class type objects, the right operand
could be an initializer list only when the assignment
is defined by a user-defined assignment operator
removed user-defined
assignment constraint
C++11 E1 = {E2} was equivalent to E1 = T(E2)
( is the type of ), this introduced a C-style cast
it is equivalent
to E1 = T{E2}
C++20 compound assignment operators for volatile
-qualified types were inconsistently deprecated
none of them
is deprecated
C++11 an assignment from a non-expression initializer clause
to a scalar value would perform direct-list-initialization
performs copy-list-
initialization instead
C++20 bitwise compound assignment operators for volatile types
were deprecated while being useful for some platforms
they are not
deprecated

[ edit ] See also

Operator precedence

Operator overloading

Common operators

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
a->b
a.b
a->*b
a.*b

function call
a(...)
comma
a, b
conditional
a ? b : c
Special operators

converts one type to another related type
converts within inheritance hierarchies
adds or removes -qualifiers
converts type to unrelated type
converts one type to another by a mix of , , and
creates objects with dynamic storage duration
destructs objects previously created by the new expression and releases obtained memory area
queries the size of a type
queries the size of a (since C++11)
queries the type information of a type
checks if an expression can throw an exception (since C++11)
queries alignment requirements of a type (since C++11)

for Assignment operators
  • Recent changes
  • Offline version
  • What links here
  • Related changes
  • Upload file
  • Special pages
  • Printable version
  • Permanent link
  • Page information
  • In other languages
  • This page was last modified on 25 January 2024, at 23:41.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

How to Overload the Bracket Operator in C++

  • How to Overload the Bracket Operator in …

Operator Overloading in C++

Overload the bracket [] operator in c++.

How to Overload the Bracket Operator in C++

This trivial programming guide overloads the bracket ( [] ) operator to be a getter and setter for the class objects.

First, let’s have a brief introduction to operator overloading.

The idea of modifying how operators behave while working with user-defined datatypes like classes and structs is known as operator overloading. These are similar to member functions in a class called when that operator is used.

For instance, assume we want to determine which employee in a class of Employees has a higher salary than the others. The > operator may be overloaded to compare the salary data member of the two objects and return the outcome.

The syntax for the operator overloading is as follows:

The optional access specifier should preferably be public . If you make it private , then the overloading function will only be able to get accessed from within the class.

This is usually undesirable in most cases.

Note that operator is a keyword used for operator overloading; after that, we specify the symbol of the operator that needs to be overloaded. Remember that we cannot overload operators for fundamental data types like int, char, float, etc.

We can also overload the [] bracket operator so that it can be used to get and set the value in a class object.

For example, we have the MyClass class with an array as a data member. To access the elements of that array using the object’s name, we can overload the [] bracket operator like this:

Note that we have returned the reference to the given index for setting the value so the user can change it. You can use it in the driver program like this:

In the above main() function, when the obj[0] = 100; is executed, it calls the second overloaded function with 0 as an argument to i . The overloaded setter method returns an integer reference to the memory space of the 0th index of arr .

The value at the right side of the assignment operator ( = ) is now assigned at the returned location. Therefore, the 0th index of the data member of obj will be given a value of 100 .

Let’s combine the above code pieces into one complete executable program.

Related Article - C++ Operator

  • Unary Negation Operator in C++
  • How to Overload Input and Output Stream Insertion Operators in C++
  • How to Overload the Addition Operator in C++
  • How to Overload the == Operator in C++
  • Arrow Operator vs. Dot Operator in C++

Learn C++ practically and Get Certified .

Popular Tutorials

Popular examples, reference materials, learn c++ interactively, introduction to c++.

  • Getting Started With C++
  • Your First C++ Program
  • C++ Comments

C++ Fundamentals

  • C++ Keywords and Identifiers
  • C++ Variables, Literals and Constants
  • C++ Data Types
  • C++ Type Modifiers
  • C++ Constants
  • C++ Basic Input/Output
  • C++ Operators

Flow Control

  • C++ Relational and Logical Operators
  • C++ if, if...else and Nested if...else
  • C++ for Loop
  • C++ while and do...while Loop
  • C++ break Statement
  • C++ continue Statement
  • C++ goto Statement
  • C++ switch..case Statement

C++ Ternary Operator

  • C++ Functions
  • C++ Programming Default Arguments

C++ Function Overloading

  • C++ Inline Functions
  • C++ Recursion

Arrays and Strings

  • C++ Array to Function
  • C++ Multidimensional Arrays
  • C++ String Class

Pointers and References

  • C++ Pointers
  • C++ Pointers and Arrays
  • C++ References: Using Pointers
  • C++ Call by Reference: Using pointers
  • C++ Memory Management: new and delete

Structures and Enumerations

  • C++ Structures
  • C++ Structure and Function
  • C++ Pointers to Structure
  • C++ Enumeration

Object Oriented Programming

  • C++ Classes and Objects
  • C++ Constructors
  • C++ Constructor Overloading
  • C++ Destructors
  • C++ Access Modifiers
  • C++ Encapsulation
  • C++ friend Function and friend Classes

Inheritance & Polymorphism

  • C++ Inheritance
  • C++ Public, Protected and Private Inheritance
  • C++ Multiple, Multilevel and Hierarchical Inheritance
  • C++ Function Overriding
  • C++ Virtual Functions
  • C++ Abstract Class and Pure Virtual Function

STL - Vector, Queue & Stack

  • C++ Standard Template Library
  • C++ STL Containers
  • C++ std::array
  • C++ Vectors
  • C++ Forward List
  • C++ Priority Queue

STL - Map & Set

  • C++ Multimap
  • C++ Multiset
  • C++ Unordered Map
  • C++ Unordered Set
  • C++ Unordered Multiset
  • C++ Unordered Multimap

STL - Iterators & Algorithms

  • C++ Iterators
  • C++ Algorithm
  • C++ Functor

Additional Topics

  • C++ Exceptions Handling
  • C++ File Handling
  • C++ Ranged for Loop
  • C++ Nested Loop
  • C++ Function Template
  • C++ Class Templates
  • C++ Type Conversion
  • C++ Type Conversion Operators

C++ Operator Overloading

Advanced topics.

  • C++ Namespaces
  • C++ Preprocessors and Macros
  • C++ Storage Class
  • C++ Bitwise Operators
  • C++ Buffers
  • C++ istream
  • C++ ostream

C++ Tutorials

  • Subtract Complex Number Using Operator Overloading
  • Increment ++ and Decrement -- Operator Overloading in C++ Programming
  • Add Complex Numbers by Passing Structure to a Function

C++ Polymorphism

C++ Operator Precedence and Associativity

In C++, we can define how operators behave for user-defined types like class and structures For example,

The + operator, when used with values of type int , returns their sum. However, when used with objects of a user-defined type, it is an error.

In this case, we can define the behavior of the + operator to work with objects as well.

This concept of defining operators to work with objects and structure variables is known as operator overloading .

  • Syntax for C++ Operator Overloading

The syntax for overloading an operator is similar to that of function with the addition of the operator keyword followed by the operator symbol.

  • returnType - the return type of the function
  • operator - a special keyword
  • symbol - the operator we want to overload ( + , < , - , ++ , etc.)
  • arguments - the arguments passed to the function
  • Overloading the Binary + Operator

Following is a program to demonstrate the overloading of the + operator for the class Complex .

Here, we first created a friend function with a return type Complex .

The operator keyword followed by + indicates that we are overloading the + operator.

The function takes two arguments:

  • Complex& indicates that we are passing objects by reference and obj1 and obj2 are references to Complex objects. This is an efficient approach because it avoids unnecessary copying, especially for large objects. To learn more, visit C++ References .
  • const indicates that referenced objects are constant, meaning we cannot modify obj1 and obj2 within the function.

Inside the function, we created another Complex object, temp to store the result of addition.

We then add the real parts of two objects and store it into the real attribute of the temp object.

Similarly, we add the imaginary parts of the two objects and store them into the img attribute of the temp object.

At last, we return the temp object from the function.

We can also overload the operators using a member function instead of a friend function. For example,

In this case, the operator is invoked by the first operand. Meaning, the line

translates to

Here, the number of arguments to the operator function is reduced by one because the first argument is used to invoke the function.

The problem with this approach is, not all the time the first operand is an object of a user-defined type. For example:

That's why it is recommended to overload operator functions as a non-member function generally, defined as a friend function.

  • Overloading ++ as a Prefix Operator

Following is a program to demonstrate the overloading of the ++ operator for the class Count .

Here, when we use ++count1; , the void operator ++ () is called. This increases the value attribute for the object count1 by 1.

Note : When we overload operators, we can use it to work in any way we like. For example, we could have used ++ to increase value by 100.

However, this makes our code confusing and difficult to understand. It's our job as a programmer to use operator overloading properly and in a consistent and intuitive way.

To overload the ++ operator as a Postfix Operator, we declare a member function operator++() with one argument having type int .

Here, when we use count1++; , the void operator ++ (int) is called. This increments the value attribute for the object count1 by 1.

Note : The argument int is just to indicate that the operator is used as a postfix operator.

  • Things to Remember in C++ Operator Overloading

1. By default, operators = and & are already overloaded in C++. For example,

we can directly use the = operator to copy objects of the same class. Here, we do not need to create an operator function.

2. We cannot change the precedence and associativity of operators using operator overloading.

3. We cannot overload following operators in C++:

  • :: (scope resolution)
  • . (member selection)
  • .* (member selection through pointer to function)
  • ?: (ternary operator)
  • sizeof operator
  • typeid Operator

4. We cannot overload operators for fundamental data types like int , float , etc

  • How to overload increment operator in right way?
  • How to overload binary operator - to subtract complex numbers?
  • Increment ++ and Decrement -- Operators

Table of Contents

  • Introduction

Sorry about that.

Related Tutorials

C++ Tutorial

  • C++ Data Types
  • C++ Input/Output
  • C++ Pointers
  • C++ Interview Questions
  • C++ Programs
  • C++ Cheatsheet
  • C++ Projects
  • C++ Exception Handling
  • C++ Memory Management

C++ Assignment Operator Overloading

Prerequisite: Operator Overloading

The assignment operator,”=”, is the operator used for Assignment. It copies the right value into the left value. Assignment Operators are predefined to operate only on built-in Data types.

  • Assignment operator overloading is binary operator overloading.
  • Overloading assignment operator in C++ copies all values of one object to another object.
  • Only a non-static member function should be used to overload the assignment operator.

We can’t directly use the Assignment Operator on objects. The simple explanation for this is that the Assignment Operator is predefined to operate only on built-in Data types. As the class and objects are user-defined data types, so the compiler generates an error.

here, a and b are of type integer, which is a built-in data type. Assignment Operator can be used directly on built-in data types.

c1 and c2 are variables of type “class C”.

The above example can be done by implementing methods or functions inside the class, but we choose operator overloading instead. The reason for this is, operator overloading gives the functionality to use the operator directly which makes code easy to understand, and even code size decreases because of it. Also, operator overloading does not affect the normal working of the operator but provides extra functionality to it.

Now, if the user wants to use the assignment operator “=” to assign the value of the class variable to another class variable then the user has to redefine the meaning of the assignment operator “=”.  Redefining the meaning of operators really does not change their original meaning, instead, they have been given additional meaning along with their existing ones.

Also, always check if the object is not being assigned to itself (e.g., if (this != &other)), as assigning an object to itself does not make sense and may cause runtime issues.

While managing dynamic resources, the above approach of assignment overloading have few flaws and there is more efficient approach that is recommended. See this article for more info – Copy-and-Swap Idiom in C++

Please Login to comment...

Similar reads.

  • cpp-operator
  • cpp-operator-overloading

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

21.10 — Overloading the parenthesis operator

Operator() is also commonly overloaded to implement functors (or function object ), which are classes that operate like functions. The advantage of a functor over a normal function is that functors can store data in member variables (since they are classes).

The nice thing about functors is that we can instantiate as many separate functor objects as we need, and use them all simultaneously. Functors can also have other member functions (e.g. reset() ) that do convenient things.

  • C++ Tutorial
  • Language Basics
  • Operators statements
  • Development
  • Operator Overloading
  • File Stream
  • STL Introduction
  • set multiset
  • queue stack
  • map multimap
  • STL Algorithms Modifying sequence operations
  • STL Algorithms Non modifying sequence operations
  • STL Algorithms Binary search
  • STL Algorithms Sorting
  • STL Algorithms Merge
  • STL Algorithms Min Max
  • STL Algorithms Iterator
  • STL Algorithms Heap
  • STL Algorithms Helper

Overload ( ) for Point : overload bracket operator « Operator Overloading « C++ Tutorial

  • overload bracket operator
Point { x, y; : Point() {} Point( px, py) { x = px; y = py; } show() { cout << x << ; cout << y << ; } Point operator+(Point op2); Point operator()( i, j); }; Point Point::operator()( i, j) { x = i; y = j; * ; } Point Point::operator+(Point op2) { Point temp; temp.x = op2.x + x; temp.y = op2.y + y; temp; } main() { Point ob1(10, 20), ob2(1, 1); ob1.show(); ob1(7, 8); ob1.show(); ob1 = ob2 + ob1(10, 10); ob1.show(); 0; }




10.9.overload bracket operator
10.9.1.Overload ( ) for Point
10.9.2.
10.9.3.
10.9.4.
10.9.5.
10.9.6.

operator overloading

(C++20)
(C++20)
(C++11)
(C++11)
(C++11)
(C++17)
General topics
(C++11)
-
-expression
- block
(C++11)
(C++11)
(C++11)
/
(C++11)
(C++11)
Expressions
expression
pointer
specifier
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
General
(lvalue, rvalue, xvalue)
(sequence points)
(C++11)
Literals
including
(C++11)
(C++11)
Operators
: , , , , , , , , , ,
: , , ,
: , , , , , , , , , , , ,
: , ,
: , , , , , , (C++20)
: , , , , , ,
: , ,
(C++20)
(C++17)
(C++11)
(C++11)
Conversions
,

Customizes the C++ operators for operands of user-defined types.

Overloaded operators are functions with special function names:

op (1)
type (2)

(3)

(4)
suffix-identifier (5) (since C++11)
op - any of the following 38 (until C++20)40 (since C++20) operators:+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= <=> (since C++20) && || ++ -- , ->* -> ( ) [ ] co_await (since C++20)

Overloaded operators

When an operator appears in an expression , and at least one of its operands has a class type or an enumeration type , then overload resolution is used to determine the user-defined function to be called among all the functions whose signatures match the following:

Expression As member function As non-member function Example
@a (a).operator@ ( ) operator@ (a) ! calls .operator!()
a@b (a).operator@ (b) operator@ (a, b) << 42 calls .operator<<(42)
a=b (a).operator= (b) cannot be non-member s; s = "abc"; calls s.operator=("abc")
a(b...) (a).operator()(b...) cannot be non-member r; auto n = r(); calls r.operator()()
a[b] (a).operator[](b) cannot be non-member <int, int> m; m[1] = 2; calls m.operator[](1)
a-> (a).operator-> ( ) cannot be non-member auto p = <S>(); p->bar() calls p.operator->()
a@ (a).operator@ (0) operator@ (a, 0) <int>::iterator i = v.begin(); i++ calls i.operator++(0)

in this table, is a placeholder representing all matching operators: all prefix operators in @a, all postfix operators other than -> in a@, all infix operators other than = in a@b

Note: for overloading user-defined conversion functions , user-defined literals , allocation and deallocation see their respective articles.

Overloaded operators (but not the built-in operators) can be called using function notation:

Restrictions

  • The operators :: (scope resolution), . (member access), .* (member access through pointer to member), and ?: (ternary conditional) cannot be overloaded.
  • New operators such as ** , <> , or &| cannot be created.
  • The overloads of operators && and || lose short-circuit evaluation.
  • The overload of operator -> must either return a raw pointer, or return an object (by reference or by value) for which operator -> is in turn overloaded.
  • It is not possible to change the precedence, grouping, or number of operands of operators.
, , and (comma) lose their special when overloaded and behave like regular function calls even when they are used without function-call notation. (until C++17)

Canonical implementations

Other than the restrictions above, the language puts no other constraints on what the overloaded operators do, or on the return type (it does not participate in overload resolution), but in general, overloaded operators are expected to behave as similar as possible to the built-in operators: operator + is expected to add, rather than multiply its arguments, operator = is expected to assign, etc. The related operators are expected to behave similarly ( operator + and operator + = do the same addition-like operation). The return types are limited by the expressions in which the operator is expected to be used: for example, assignment operators return by reference to make it possible to write a = b = c = d , because the built-in operators allow that.

Commonly overloaded operators have the following typical, canonical forms: [1]

Assignment operator

The assignment operator ( operator = ) has special properties: see copy assignment and move assignment for details.

The canonical copy-assignment operator is expected to perform no action on self-assignment , and to return the lhs by reference:

The canonical move assignment is expected to leave the moved-from object in valid state (that is, a state with class invariants intact), and either do nothing or at least leave the object in a valid state on self-assignment, and return the lhs by reference to non-const, and be noexcept:

In those situations where copy assignment cannot benefit from resource reuse (it does not manage a heap-allocated array and does not have a (possibly transitive) member that does, such as a member std::vector or std::string ), there is a popular convenient shorthand: the copy-and-swap assignment operator, which takes its parameter by value (thus working as both copy- and move-assignment depending on the value category of the argument), swaps with the parameter, and lets the destructor clean it up.

This form automatically provides strong exception guarantee , but prohibits resource reuse.

Stream extraction and insertion

The overloads of operator>> and operator<< that take a std:: istream & or std:: ostream & as the left hand argument are known as insertion and extraction operators. Since they take the user-defined type as the right argument ( b in a@b ), they must be implemented as non-members.

These operators are sometimes implemented as friend functions .

Function call operator

When a user-defined class overloads the function call operator, operator ( ) , it becomes a FunctionObject type. Many standard algorithms, from std:: sort to std:: accumulate accept objects of such types to customize behavior. There are no particularly notable canonical forms of operator ( ) , but to illustrate the usage

Increment and decrement

When the postfix increment and decrement appear in an expression, the corresponding user-defined function ( operator ++ or operator -- ) is called with an integer argument 0 . Typically, it is implemented as T operator ++ ( int ) , where the argument is ignored. The postfix increment and decrement operator is usually implemented in terms of the prefix version:

Although canonical form of pre-increment/pre-decrement returns a reference, as with any operator overload, the return type is user-defined; for example the overloads of these operators for std::atomic return by value.

Binary arithmetic operators

Binary operators are typically implemented as non-members to maintain symmetry (for example, when adding a complex number and an integer, if operator+ is a member function of the complex type, then only complex + integer would compile, and not integer + complex ). Since for every binary arithmetic operator there exists a corresponding compound assignment operator, canonical forms of binary operators are implemented in terms of their compound assignments:

Relational operators

Standard algorithms such as std:: sort and containers such as std:: set expect operator < to be defined, by default, for the user-provided types, and expect it to implement strict weak ordering (thus satisfying the Compare requirements). An idiomatic way to implement strict weak ordering for a structure is to use lexicographical comparison provided by std::tie :

Typically, once operator < is provided, the other relational operators are implemented in terms of operator < .

Likewise, the inequality operator is typically implemented in terms of operator == :

When three-way comparison (such as std::memcmp or std::string::compare ) is provided, all six relational operators may be expressed through that:

All six relational operators are automatically generated by the compiler if the three-way comparison operator operator<=> is defined, and that operator, in turn, is generated by the compiler if it is defined as defaulted:

Record { name; unsigned int floor; double weight; auto operator<=>(const Record&) = default; }; // records can now be compared with ==, !=, <, <=, >, and >=

See for details.

(since C++20)

Array subscript operator

User-defined classes that provide array-like access that allows both reading and writing typically define two overloads for operator [ ] : const and non-const variants:

If the value type is known to be a built-in type, the const variant should return by value.

Where direct access to the elements of the container is not wanted or not possible or distinguishing between lvalue c [ i ] = v ; and rvalue v = c [ i ] ; usage, operator[] may return a proxy. see for example std::bitset::operator[] .

To provide multidimensional array access semantics, e.g. to implement a 3D array access a [ i ] [ j ] [ k ] = x ; , operator[] has to return a reference to a 2D plane, which has to have its own operator[] which returns a reference to a 1D row, which has to have operator[] which returns a reference to the element. To avoid this complexity, some libraries opt for overloading operator ( ) instead, so that 3D access expressions have the Fortran-like syntax a ( i, j, k ) = x ;

Bitwise arithmetic operators

User-defined classes and enumerations that implement the requirements of BitmaskType are required to overload the bitwise arithmetic operators operator & , operator | , operator ^ , operator~ , operator & = , operator | = , and operator ^ = , and may optionally overload the shift operators operator << operator >> , operator >>= , and operator <<= . The canonical implementations usually follow the pattern for binary arithmetic operators described above.

Boolean negation operator

The operator operator ! is commonly overloaded by the user-defined classes that are intended to be used in boolean contexts. Such classes also provide a user-defined conversion function explicit operator bool ( ) (see std::basic_ios for the standard library example), and the expected behavior of operator ! is to return the value opposite of operator bool .

Rarely overloaded operators

The following operators are rarely overloaded:

  • The address-of operator, operator & . If the unary & is applied to an lvalue of incomplete type and the complete type declares an overloaded operator & , the behavior is undefined (until C++11) it is unspecified whether the operator has the built-in meaning or the operator function is called (since C++11) . Because this operator may be overloaded, generic libraries use std::addressof to obtain addresses of objects of user-defined types. The best known example of a canonical overloaded operator& is the Microsoft class CComPtr . An example of its use in EDSL can be found in boost.spirit .
  • The boolean logic operators, operator && and operator || . Unlike the built-in versions, the overloads cannot implement short-circuit evaluation. Also unlike the built-in versions, they do not sequence their left operand before the right one. (until C++17) In the standard library, these operators are only overloaded for std::valarray .
  • The comma operator, operator, . Unlike the built-in version, the overloads do not sequence their left operand before the right one. (until C++17) Because this operator may be overloaded, generic libraries use expressions such as a, void ( ) ,b instead of a,b to sequence execution of expressions of user-defined types. The boost library uses operator, in boost.assign , boost.spirit , and other libraries. The database access library SOCI also overloads operator, .
  • The member access through pointer to member operator - > * . There are no specific downsides to overloading this operator, but it is rarely used in practice. It was suggested that it could be part of smart pointer interface , and in fact is used in that capacity by actors in boost.phoenix . It is more common in EDSLs such as cpp.react .

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
C++11 taking address of incomplete type that overloads address-of was undefined behavior the behavior is only unspecified
  • Operator precedence
  • Alternative operator syntax
Common operators

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[b]
*a
&a
a->b
a.b
a->*b
a.*b

a(...)
a, b
? :

Special operators

converts one type to another related type
converts within inheritance hierarchies
adds or removes qualifiers
converts type to unrelated type
converts one type to another by a mix of , , and
creates objects with dynamic storage duration
destructs objects previously created by the new expression and releases obtained memory area
queries the size of a type
queries the size of a (since C++11)
queries the type information of a type
checks if an expression can throw an exception (since C++11)
queries alignment requirements of a type (since C++11)

  • ↑ Operator Overloading on StackOverflow C++ FAQ
  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

How do I overload the square-bracket operator in C#?

DataGridView, for example, lets you do this:

but for the life of me I can't find the documentation on the index/square-bracket operator. What do they call it? Where is it implemented? Can it throw? How can I do the same thing in my own classes?

ETA: Thanks for all the quick answers. Briefly: the relevant documentation is under the "Item" property; the way to overload is by declaring a property like public object this[int x, int y]{ get{...}; set{...} } ; the indexer for DataGridView does not throw, at least according to the documentation. It doesn't mention what happens if you supply invalid coordinates.

ETA Again: OK, even though the documentation makes no mention of it (naughty Microsoft!), it turns out that the indexer for DataGridView will in fact throw an ArgumentOutOfRangeException if you supply it with invalid coordinates. Fair warning.

  • collections
  • operator-overloading

Coderer's user avatar

8 Answers 8

you can find how to do it here . In short it is:

If you only need a getter the syntax in answer below can be used as well (starting from C# 6).

Ruben's user avatar

  • 9 a minor comment: depending on what you're doing, you might find it more appropriate to do: get { return base[i]; } set { base[i] = value; } –  MikeBaz - MSFT Commented Oct 4, 2012 at 21:58
  • 9 This isn't operator overloading. It is indexer –  Destructor Commented May 12, 2016 at 8:32
  • 6 Indexer, may as well be a unary operator. –  alan2here Commented Aug 9, 2016 at 12:27
  • 1 In 2019, a new answer should be selected, this one . Too bad SO doesn't have a feature to deal with deprecated answers, as the new one is not close to get 350+ upvotes, though it deserves them. –  mins Commented Jul 3, 2019 at 16:52

That would be the item property: http://msdn.microsoft.com/en-us/library/0ebtbkkc.aspx

Maybe something like this would work:

Ricardo Villamil's user avatar

  • Thanks a lot! If I could set two answers, I'd add yours as well -- nobody else knew to look for Item in the documentation... –  Coderer Commented Nov 13, 2008 at 19:34
  • 5 In terms of how it gets implemented, it is "Item", but in C# terms, it is "this" –  Marc Gravell Commented Nov 13, 2008 at 21:43
  • 1 Right, but I asked "for the life of me I can't find the documentation on the index/square-bracket operator" -- I meant when you look up a library class in MSDN, where do they tell you about the operator? That's why I made that last "ETA" about what it throws -- the docs are wrong . –  Coderer Commented Nov 14, 2008 at 14:59

Source of the information

For bracket:

The array indexing operator cannot be overloaded ; however, types can define indexers, properties that take one or more parameters. Indexer parameters are enclosed in square brackets, just like array indices, but indexer parameters can be declared to be of any type (unlike array indices, which must be integral).

dimitar.bogdanov's user avatar

  • yes it can be overloaded, as long as the parameter signature is different, exactly like any other method's overloading restrictions –  Charles Bretana Commented Nov 13, 2008 at 19:40
  • It can, but not for the condition I wrote. It's from MSDN. Check the source if you do not believe me –  Patrick Desjardins Commented Nov 13, 2008 at 20:13
  • 2 Sorry if I misread your post, but what condition are you referring to? –  Charles Bretana Commented Nov 13, 2008 at 21:00
  • +1 for the handy list. FYI the link died. (4 years later, I know) –  Mixxiphoid Commented Mar 4, 2013 at 21:04
  • I'd like to add that you can override both implicit and explicit type-casting in C# now. –  Felype Commented Sep 15, 2017 at 13:53

If you're using C# 6 or later, you can use expression-bodied syntax for get-only indexer:

public object this[int i] => this.InnerList[i];

amoss's user avatar

  • 6 Actually, this is really dangerous - you now have two competing implementations: anyone with a variable typed as List<T> or IList<T> or IList etc won't execute your custom code. –  Marc Gravell Commented Nov 13, 2008 at 21:35
  • 1 Agreed -- if nothing else, it's not necessary to derive your CustomCollection from List, but I hadn't realized it was actually dangerous –  Coderer Commented Nov 14, 2008 at 14:58
  • It will still execute the custom code though, won't it? It doesn't matter what variable type you declare - it's the type of the object that matters. –  izb Commented Nov 11, 2010 at 15:53
  • 1 Friendly reminder of C# polymorphism: That happens because the base class doesn't declare its implementation as virtual. If it were declared as virtual, the custom code would be called in every case. –  almulo Commented May 20, 2015 at 12:03
  • 1 Also, this code will give you a compiler warning since both indexers are non-virtual. The compiler will suggest that you qualify your custom indexer with the new keyword. –  amoss Commented May 18, 2016 at 18:48

Here is an example returning a value from an internal List object. Should give you the idea.

Rob Prouse's user avatar

For CLI C++ (compiled with /clr) see this MSDN link .

In short, a property can be given the name "default":

If you mean the array indexer,, You overload that just by writing an indexer property.. And you can overload, (write as many as you want) indexer properties as long as each one has a different parameter signature

vzwick's user avatar

  • 2 First, you mean this[], not this() - however, providing a custom (but different) this[int] on something that is a list (IList/IList<T>/List<T>) is quite dangerous - and could lead to subtle bugs between the "int index" and "int employeeId" versions. Both are still callable. –  Marc Gravell Commented Nov 13, 2008 at 21:40
  • and in fact, I don;t think the code I entered above would compile without adding a new or override statement precisely because of the existence of the List<T> implementation of this[int]. You're right about the potential when doing this, simply meant it as example of overloading indexer. –  Charles Bretana Commented Nov 13, 2008 at 21:48

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged c# collections operators operator-overloading or ask your own question .

  • The Overflow Blog
  • The framework helping devs build LLM apps
  • How to bridge the gap between Web2 skills and Web3 workflows
  • Featured on Meta
  • Upcoming initiatives on Stack Overflow and across the Stack Exchange network...
  • Announcing a change to the data-dump process
  • What makes a homepage useful for logged-in users

Hot Network Questions

  • I am testing the flyweight pattern on thousands of GameObjects but its not helping save memory. What am I doing wrong here?
  • Why don't we call value investing "timing the market"?
  • What are good reasons for declining to referee a manuscript that hasn't been posted on arXiv?
  • Why can THHN/THWN go in Schedule 40 PVC but NM cable (Romex) requires Schedule 80?
  • Narcissist boss won't allow me to move on/sabotaged internal transfer
  • Is "farfel" an idiolectical quirk/part of a familect?
  • Does the question "will I get transplanted" make sense to your ears?
  • Would it be possible to start a new town in America with its own political system?
  • How can I connect my thick wires into an ikea wire connector
  • Does pruning my pine tree rectangularly strengthen roots, and could they reach my house?
  • Reducing required length of a mass driver using loop?
  • How important is Waterdeep: Dragon Heist to the story of Waterdeep: Dungeon of the Mad Mage?
  • Why did C++ standard library name the containers map and unordered_map instead of map and ordered_map?
  • Did Arab Christians use the word "Allah" before Islam?
  • Find the segment "DC" in the obtuse triangle below
  • Always orient a sundial towards polar north?
  • Left crank arm misaligned on climb
  • Can your boss take vouchers from you, offered from suppliers?
  • Is it rude to ask Phd student to give daily report?
  • Homebrew DND 5e Spell, review in power, and well... utility
  • Detailed exposition of construction of Steenrod squares from Haynes Miller's book
  • What is the name of the floor pump part that depresses the valve stem?
  • Declension in book dedication
  • Symbol denoting parity eigenvalue

overload bracket operator c assignment

IMAGES

  1. Overloading C++ "Assignment Operator =" with Example

    overload bracket operator c assignment

  2. Assignment Operator Overloading in C++

    overload bracket operator c assignment

  3. Operator Overloading in c++

    overload bracket operator c assignment

  4. C++ Operator Overloading (With Examples)

    overload bracket operator c assignment

  5. C++ Overload Cast Operator: Mastering Type Conversions

    overload bracket operator c assignment

  6. C++ Classes: Overloading the double angle bracket operator

    overload bracket operator c assignment

VIDEO

  1. Overloading operators

  2. 19. Overloading Unary Operator ++

  3. Overloading Operators in C#

  4. C++ Overloading Math Operator in Class [5]

  5. Assignment Operators in C Programming

  6. Basics of operator overloading in C++ (#1)

COMMENTS

  1. Overloading bracket assignment in C++

    5. What you typically do in this situation is to implement: Object const& Map::operator[](string) const; Object& Map::operator[](string); Note that I wrote Object& instead of Object. You can at any rate instantiate a new Object and hand it out, relying on a proper Object& Object::operator=(Object const&) to be implemented, which will then ...

  2. operator overloading

    What you're looking for is functionality similar to the overloaded bracket operator in std::map. In std::map the bracket operator performs a lookup and returns a reference to an object associated with a particular key. If the map does not contain any object associated with the key, the operator inserts a new object into the map using the ...

  3. c++

    unsigned long operator [](int i) const {return registers[i];} unsigned long & operator [](int i) {return registers[i];} You can also return a const long&. If it weren't a native type then that way would be preferred but for types like long it's fine to return it by value. Note that it would be a good idea to add a test on i to make sure it's a ...

  4. Member access operators

    1) If the operand is an lvalue expression of some object or function type T, operator& creates and returns a prvalue of type T*, with the same cv qualification, that is pointing to the object or function designated by the operand.If the operand has incomplete type, the pointer can be formed, but if that incomplete type happens to be a class that defines its own operator &, it is unspecified ...

  5. operator overloading

    When an operator appears in an expression, and at least one of its operands has a class type or an enumeration type, then overload resolution is used to determine the user-defined function to be called among all the functions whose signatures match the following: Expression. As member function. As non-member function.

  6. PDF Operator Overloading

    Overloading Bracket Operators Let's begin our descent into the realm of operator overloading by discussing the overloaded bracket [ ] operator. You've been using the overloaded bracket operator ever since you encountered the string and vector classes. For example, the following code uses the vector's overloaded brackets: for(int i = 0; i < myVector.size(); i++)

  7. Assignment operators

    for assignments to class type objects, the right operand could be an initializer list only when the assignment is defined by a user-defined assignment operator. removed user-defined assignment constraint. CWG 1538. C++11. E1 ={E2} was equivalent to E1 = T(E2) ( T is the type of E1 ), this introduced a C-style cast. it is equivalent to E1 = T{E2}

  8. Assignment Operators in C

    Assignment operator overloading is binary operator overloading.Overloading assignment operator in C++ copies all values of one. 4 min read. Conversion Operators in C++. ... Explanation: The bracket operator has higher precedence than assignment operator. The expression within bracket operator is evaluated from left to right but it is always the res

  9. How to Overload the Bracket Operator in C++

    Overload the Bracket [] Operator in C++. We can also overload the [] bracket operator so that it can be used to get and set the value in a class object. For example, we have the MyClass class with an array as a data member. To access the elements of that array using the object's name, we can overload the [] bracket operator like this:

  10. 21.1

    In lesson 11.1 -- Introduction to function overloading, you learned about function overloading, which provides a mechanism to create and resolve function calls to multiple functions with the same name, so long as each function has a unique function prototype.This allows you to create variations of a function to work with different data types, without having to think up a unique name for each ...

  11. C++ Operator Overloading (With Examples)

    Things to Remember in C++ Operator Overloading. 1. By default, operators = and & are already overloaded in C++. For example, we can directly use the = operator to copy objects of the same class. Here, we do not need to create an operator function. 2. We cannot change the precedence and associativity of operators using operator overloading. 3.

  12. operator overloading

    Overloaded operators. When an operator appears in an expression, and at least one of its operands has a class type or an enumeration type, then overload resolution is used to determine the user-defined function to be called among all the functions whose signatures match the following: Expression. As member function.

  13. 21.12

    21.12 — Overloading the assignment operator. Alex November 27, 2023. The copy assignment operator (operator=) is used to copy values from one object to another already existing object. As of C++11, C++ also supports "Move assignment". We discuss move assignment in lesson 22.3 -- Move constructors and move assignment .

  14. overload assignment and round bracket operator in C++

    Member functions, including operators, can be overloaded on const-ness (the this pointer is effectively a parameter and takes part in overload resolution). double& operator()(int i) { return _v[i]; } double operator()(int i) const { return _v[i]; } NOTE: With non-member operators, the left-hand object isn't just like a parameter, it IS a parameter.

  15. operator overloading

    Rarely overloaded operators. The following operators are rarely overloaded: The address-of operator, operator &. If the unary & is applied to an lvalue of incomplete type and the complete type declares an overloaded operator &, the behavior is undefined (until C++11) it is implementation-defined whether the overloaded operator is used (since ...

  16. C++ Assignment Operator Overloading

    The assignment operator,"=", is the operator used for Assignment. It copies the right value into the left value. Assignment Operators are predefined to operate only on built-in Data types. Assignment operator overloading is binary operator overloading. Overloading assignment operator in C++ copies all values of one object to another object.

  17. operator overloading

    Overloaded operators. When an operator appears in an expression, and at least one of its operands has a class type or an enumeration type, then overload resolution is used to determine the user-defined function to be called among all the functions whose signatures match the following: Expression. As member function.

  18. 21.10

    The parenthesis operator (operator ()) is a particularly interesting operator in that it allows you to vary both the type AND number of parameters it takes. There are two things to keep in mind: first, the parenthesis operator must be implemented as a member function. Second, in non-object-oriented C++, the () operator is used to call functions.

  19. Overload ( ) for Point : overload bracket operator « Operator ...

    The overloaded operator[ ]( ) function returns the value of the array as indexed by the value of its parameter. 10.9.4. design the operator[ ]( ) function in such a way that the [ ] can be used on both the left and right sides of an assignment statement. 10.9.5. Add a range check to for overloaded [] operator: 10.9.6. Overload operator for two ...

  20. operator overloading

    When a user-defined class overloads the function call operator, operator(), it becomes a FunctionObject type. Many standard algorithms, from std::sort to std::accumulate accept objects of such types to customize behavior. There are no particularly notable canonical forms of operator(), but to illustrate the usage.

  21. How do I overload the square-bracket operator in C#?

    But in C#, these operators are automatically overloaded when the respective binary operator is overloaded. =, . , ?:, ->, new, is, as, sizeof These operators can't be overloaded [ ] Can be overloaded but not always! Source of the information. For bracket: public Object this [int index] { }