"ref const" parameters in functions

Jonathan M Davis jmdavisProg at gmx.com
Sat Mar 31 14:41:51 PDT 2012


On Saturday, March 31, 2012 23:25:51 L-MAN wrote:
> Hello everybody!
> 
> I'm trying to use some function FN like this:
> 
> struct X
> {
>   protected double _x;  // double type for example
>   public @property double X() const { return _x; }
> 
>   // ctor
>   public this(double x) { _x = x; } // double type for example
> 
>   void FN(ref const(double) in_x) // double type for example
>   {
>     // ... do some operations with _x
>   }
> 
> }
> 
> main(..)
> {
>   ....
>   X x = X(20);
> 
>   x.FN(30); // getting an error
> }
> 
> 
>   why x.FN(20) gets me an error?
>   the construction "ref const(double)" or "ref immutable(double)"
> must be an rvalue by default I think, but in FN parameter the
> compiler expects an lvalue...
>   this strategy is the way to some unnecessary copy operations,
> when value 20 (or some big struct instead of it) will copy to the
> stack..
> 
> How can I resolve this problem?

Unlike C++, const ref _must_ be an lvalue just like ref. If you use auto ref 
instead of const ref, the compiler is supposed to choose between ref and non-
ref based on which it thinks would be more efficient, but it currently only 
works with templated types.

You can duplicate the function and have a version whose parameter is const ref 
and one which is not, but be careful if you try and make the non-const ref 
version call the const ref version (to avoid duplicating the function's body) 
and make sure that you don't get infinite recursion. It usually works, but I've 
run into cases before where I ended up with infinite recursion, so make sure 
that you have unit tests which check.

Regardless, if you're dealing with a primitive type like double, don't bother 
with const ref. It's not going to be more efficient. It's with large structs 
that you can see a difference.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list