Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Cast operator overloading and references

C++ allows for overloading type casts by creating an operator T() where T is the type we want to cast to.

Now, how does this feature play together with references? For example:

struct Y{ int i; };

struct X{
    Y y;

    operator Y() const { return y; }
};

Here, we can cast an X to Y which will simply return the contained Y. But what if we want to make a cast to an Y reference. For example, C++ allows us to do this:

struct X{
    Y y;

    operator Y&(){ return y; }
    operator const Y&() const { return y; }
};

Now, we can cast an X to a Y reference or a const reference (which also works for a const X).

Is there any difference in the semantics of the first and the second example? What is the best way if I want to allow casting to a reference?

I could imagine that even if I write operator T() without any &, C++ might allow that the cast returns a result by reference (i.e., it might somehow add implicit operator T&() methods when I specify operator T()).

For example, I want the following code to work:

int main(){
    X x;
    Y& y = x; // y now references the y inside x
    y.i = 5;
    std::cout << x.y.i << std::endl; // Should print 5 now
}

What is the most simple way to achieve this?

like image 490
gexicide Avatar asked Aug 14 '14 08:08

gexicide


People also ask

Why do we use reference in operator overloading?

You would want an expression, a + b , to return a reference to one of a or b, which would have the results of the expression. Thus you would modify one of a or b to be the sum of a and b. So you would want to redefine the semantics of the operator (+) to be the same as the operator (+=).

What is cast operator in C?

Cast operator () In C, the result of the cast operation is not an lvalue. In C++, the cast result belongs to one of the following value categories: If type is an lvalue reference type. or an rvalue reference to a function type.

What is operator overloading with example in C?

Here, + is a binary operator that works on the operands num and 9 . When we overload the binary operator for user-defined types by using the code: obj3 = obj1 + obj2; The operator function is called using the obj1 object and obj2 is passed as an argument to the function.

Is there operator overloading in C?

C does not support operator overloading (beyond what it built into the language).


2 Answers

Does declaring a operator T() imply that the cast always returns a T by value?

Yes.

The return type of conversion operators is implicitly exactly what they convert to.

[...] the type of the conversion function is “function taking no parameter returning conversion-type-id”.

§12.3.2 [class.conv.fct]

like image 131
Robert Allan Hennigan Leahy Avatar answered Sep 20 '22 23:09

Robert Allan Hennigan Leahy


With clang++:

#include <iostream>

class   test
{
public:
  test(int n) : nb{n} {}

public:
  operator int() { return nb; }

  private:
    int nb;
};

int     main(void)
{
  test  t{42};

  int x = t;

  int& ref = t;   // error: non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'test'
  int&& rref = t; // compiles fine

  std::cout << x << std::endl;
}

Which suggest that you do return a temporary new value.

The real question to help you choose between your two cases is: do you want to let people modify your internal member (return a reference) and is that member expensive to copy (use a const reference instead of value) ?

like image 45
Drax Avatar answered Sep 17 '22 23:09

Drax