14

is it possible to discern between these two methods? should one not mutate an rvalue when in this case seems perfectly reusable?

TYPE a;
TYPE b = -a;      // unary operator- of a TYPE& aka lvalue ref
TYPE c = -(a+b);  // unary operator- of a TYPE&& aka rvalue ref
Anon
  • 155
  • 6
  • `a` and `a+b` are *lvalue* and *prvalue* (if TYPE is builtin or its `operator+` returns by value); they aren't references – M.M Jun 10 '16 at 09:23

2 Answers2

15

You can use reference qualifier-s (or ref-qualifiers as in standard)

http://coliru.stacked-crooked.com/a/40905649dc0c14e7

example:

#include <iostream>
#include <string>
#include <vector>

class X
{
   public:
      int n;
      X(const X&) = default;
      X() : n(0) {}
      X(int n) : n(n) {}

      X operator- () const &  // lvalue ref-qualifier
      {
         std::cout << "&\n";
         X x(-n);
         return x;
      }

      X operator- () const && // rvalue ref-qualifier
      {
         std::cout << "&&\n";
         X x(-n);
         return x;
      }    

      friend X operator+(const X& lhs, const X& rhs) {
          return X(lhs.n + rhs.n);
      }
};

int main()
{
    X a;
    X b = -a;      // unary operator- of a TYPE& aka lvalue ref
    X c = -(a+b);
}

outputs:

&
&&
marcinj
  • 48,511
  • 9
  • 79
  • 100
12

Something like:

class Type
{
public:
    Type& operator -() && { std::cout << "rvalue\n";  return *this; }
    Type& operator -() & { std::cout << "lvalue\n";  return *this; }
};

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302