1

Say I have a class with an overridden assignment operator:

class Test
{
public:
    Test& operator =(const Test&) {return *this;}
};

Test f();

Is there any way to make it a compile-time error to assign to the result of a function?

Examples:

f() = test();

Test t;
f() = t;

// if there were also a Test Test::operator+(Test);
(t + t) = test();

This already happens for primitive types, and I want to replicate it for this class:

int g();
g() = 5; // error
(3 + 4) = 5; // error

Edit: I'm using Visual C++, which doesn't support all of C++11. Specifically, it doesn't support ref-qualifiers.

user253751
  • 57,427
  • 7
  • 48
  • 90

2 Answers2

6

If you don't want your operator=() to be invoked on temporaries (rvalues), then qualify it lvalue as:

Test& operator =(const Test&) & {return *this;}
                           //^^^ note this

Now the following

f() = t;

will give compilation error.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 1
    @Jarod42: Yes. It has been more than 2 years since C++11 is released. So I would assume C++11 is the default now, unless specifically specified. – Nawaz Jan 31 '14 at 11:10
  • This is a good answer for the question I asked, but I forgot to mention I'm using Visual C++ which doesn't support these. – user253751 Jan 31 '14 at 11:14
  • @immibis: Ohh.. in that case, you don't have any ideal solution now. Anyway, I will keep this answer for educational purpose as it might help others! – Nawaz Jan 31 '14 at 11:17
  • 1
    @Nawaz That's not very realistic. It usually takes at least 5 years for a new version of the standard to be widely and reliably implemented. – James Kanze Jan 31 '14 at 12:13
0

In C++11, you can ref-qualify your assignment operator so that it can only be called on lvalue references. However, I can't find anything definite in the standard about whether such an operator is still the copy assignment operator.

In C++03, people came up with the idea of only returning const objects from functions, but that's a bad idea because it prevents moving in C++11.

In the end, it's probably not worth going to any effort to do this.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157