Const ref and rvalue in D

the code

struct CustomReal
{
   private real value;

   this(real value)
   {
      this.value = value;
   }

   CustomReal opBinary(string op)(CustomReal rhs) if (op == "+")
   {
      return CustomReal(value + rhs.value);
   }

   bool opEquals(ref const CustomReal x) const
   {
      return value == x.value; // just for fun
   }
}

// Returns rvalue 
CustomReal Create()
{
   return CustomReal(123.123456);
}

void main()
{
   CustomReal a = Create();
   assert(a == CustomReal(123.123456)); // OK. CustomReal is temporary but lvalue
   assert(a == Create());               // Compilation error (can't bind to rvalue)
   assert(a != a + a);                  // Compilation error (can't bind to rvalue)
}

Compilation error

prog.d(31): Error: function prog.CustomReal.opEquals (ref const const(CustomReal) x) const is not callable using argument types (CustomReal)
prog.d(31): Error: Create() is not an lvalue

http://ideone.com/O8wFc

Questions:

  • Why const refcan't contact rvalue? This is normal?
  • Do I need to return to ref CustomRealor const ref CustomRealfrom opBinary()to fix this problem? This is normal?
  • Is it correct to return a link to a local object created on the stack? ref CustomReal Create() { return CustomReal(0.0); }
+5
source share
3 answers

The only difference between refand const refis that which const refis constand refis not. Both should take a variable. None of them can be temporary. This is different from C ++, where it const T&will take any type value T- including temporary ones.

opBinary ref, const ref, . . Create. , , , . , .

, opEquals:

bool opEquals(CustomReal x) const
{
    return value == x.value; // just for fun
}

.

, opEquals . , opEquals, , , , , , :

prog.d(15): Error: function prog.CustomReal.opEquals type signature should be const bool(ref const(CustomReal)) not const bool(CustomReal x)

opEquals structs ( , toString, ). , , . opEquals. CustomReal , const ref, CustomReal , . , .

,

assert(a == CustomReal(123.123456));

,

assert(a == Create());  

, . , , , const ref , - - , , opEquals special. , , opEquals , , , , . opEquals .

EDIT: , ,

assert(a == CustomReal(123.123456));

,

assert(a == Create());

, ( , ) lvalue, , ref (), r. , , rvalues, , -, lvalues ​​ ( ). , , const ref, , .

+4

#1: Yep, const ref rvalues. , ++ IIRC. http://digitalmars.com/d/archives/digitalmars/D/const_ref_rvalues_103509.html#N103514

, lvalues ​​ D2, :

struct A {}
void foo(ref A a) {}
void main()
{
    foo(A());
}

:

static A bar()
{
    return A();
}

foo(bar());
+3

For # 2 (and by extension # 3): No, that would be invalid because it would have to be a reference to an object that just went out of scope.

+2
source

All Articles