What Is Return Type of Assignment Operator

what is return type of assignment operator?

The standard correctly defines the return type of an assignment operator.
Actually, the assignment operation itself doesn't depend on the return value - that's why the return type isn't straightforward to understanding.

The return type is important for chaining operations.
Consider the following construction: a = b = c;. This should be equal to a = (b = c), i.e. c should be assigned into b and b into a. Rewrite this as a.operator=(b.operator=(c)). In order for the assignment into a to work correctly the return type of b.operator=(c) must be reference to the inner assignment result (it will work with copy too but that's just an unnecessary overhead).

The dereference operator return type depends on your inner logic, define it in the way that suits your needs.

Return type of assignment operator in C++

The return type doesn't have to be A&; the standard only says:

A user-declared copy assignment operator X​::​operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X&, or const volatile X&.

We do that by convention.

The oft-cited argument is that you can then "chain" assignments (a = b = c), though to be honest that's not exactly a common pattern. I consider it to be cargo cult programming to some degree, but it doesn't hurt anybody and it's nice to have consistency.

The downside is that most people don't even make use of such a return type, and sometimes the actual reason for it can get lost (as per this question!).

We don't return an A, because returning by value (i.e. returning a _copy) of the operated-on object) instead would be even less useful, and would confuse the purpose of the assignment operator, which is not to create a new A.

What does assignment operator means in return statements, like return t =...?

In the return instructions, the operator assigns to t which is a reference (modifies it) then returns the value.

That's what an incrementation operator does: modifies & returns reference at the same time so the incremented value can be used in another operation.

Low level details of C/C++ assignment operator implementation. What does it return?

For built-in types in C++ evaluating an assignment expression produces an lvalue that is the left hand side of the assignment expression. The assignment is sequenced before the result can be used, so when the result is converted to an rvalue you get the newly assigned value:

int a, b=5;
int &c = (a=b);
assert(&c==&a);
b=10;
assert(10==(a=b));

C is almost but not exactly the same. The result of an assignment expression in C is an rvalue the same as the value newly assigned to the left hand side of the assignment.

int *c = &(a=b); // not legal in C because you can only take the address of lvalues.

Usually if the result of an assignment is used at all it's used as an rvalue (e.g., a=b=c), so this difference between C++ and C largely goes unnoticed.

Return type of assignment operator

Your class does not meet the CopyAssignable concept (§17.6.3.1) so it is no longer guaranteed by the standard to work with the standard containers that require this (e.g. std::vector requires this for insert operations).

Besides that, this behavior is not idiomatic and will be perceived as surprising by programmers using your code. If you want to disallow chaining, consider adding a named function that does the assignment instead.

Just don't try to change the behavior of idiomatic operators in subtle ways like this. It will make your code harder to read and maintain.

Return type for the assignment operator

The first version allows to do further operations on the returned object in one line as in

(refobj = a).do_something();

When you don't return a reference to the object, this is not possible. You may think this is silly, but think about output operators.

void operator<<(std::ostream &out, const Obj1 &obj1);
std::ostream& operator<<(std::ostream &out, const Obj2 &obj2);

Obj1 obj1;
Obj2 obj2;
std::cout << obj1 << '\t' << obj1 << std::endl; // compiler error
// ^^^^ '<<' can't operate on void
std::cout << obj2 << '\t' << obj2 << std::endl; // works!
// ^^^^ return type is std::ostream, '<<' work on that

Given that returning a reference is really cheap, I recommend to always return one. This will save you the pain of searching for strange bugs where otherwise perfectly sane syntax will break your code.

Return value of assignment operator overloading c++

A pointer is a data type that holds a memory address of the type the pointer points to, or nullptr if it doesn't refer to anything. (Or a dangling pointer, or a garbage value... but that's a bad place.)

So dereferencing a pointer by *this means that you are now dealing with the object pointed to by the pointer. Which is why this->foo and (*this).foo do the same thing.

Why does C++ have a this pointer, rather than (say) a self reference? That's just how C++ evolved, which Bjarne Stroustrup discusses at length in his excellent book The Design and Evolution of C++.

Back to your operator= situation. In C++, you can typically do this kind of construct: x = y = z;, which is ordered like x = (y = z); due to the right-to-left association of assignment.

If your assignment was void operator=(Fraction const&) then it could not be used to do assignment chaining. Not supporting assignment chaining would be "friction" for anyone used to the expected behavior of assignment and how C++ built-in types allow chaining.

Why return Fraction& versus Fraction object, is more than a simple performance optimization. Because if you did (x = y).negate(); the hypothetical negate method would be operating on a temporary rather than on x.



Related Topics



Leave a reply



Submit