Using in as a parameter qualifier

Jonathan M Davis jmdavisProg at gmx.com
Fri May 31 08:25:27 PDT 2013


On Friday, May 31, 2013 15:10:01 Shriramana Sharma wrote:
> On Fri, May 31, 2013 at 12:12 PM, Ali Çehreli <acehreli at yahoo.com> wrote:
> >> Consider a function that operates on a pair:
> >> double abs2 ( pair a ) { return a.x * a.x + a.y * a.y ; }
> >> In C++ the function signature would be: double abs2 ( const pair & a )
> >> So I thought const ref pair a would be appropriate in D -- is that right?
> > 
> > Yes:
> > double abs2(ref const(Pair) a) { /* ... */ }
> 
> But is this the idiomatic D way of doing things? I mean, would one
> normally prefer in or ref const(T) which somehow seems more awkward
> than even const T &?

In D, const ref does not accept rvalues (unlike C++'s const &). So, if you use 
const ref, odds are that you need to duplicate the function

double abs2(ref const(Pair) a) {...}
double abs2(const Pair a) { abs2(a); /* calls the const ref overload */ }

If a function is templated, you can use auto ref to avoid the duplication

double abs2()(auto ref Pair a) {...}

or if you want const

double abs2()(auto ref const Pair a) {...}

auto ref is not currently implemented for non-templated functions, so if you 
want to use it, you have to templatize the function (the two examples above 
have empty template parameter lists just to templatize the function). auto ref 
makes it so that the function will accept both lvalues and rvalues (it 
generates a function that accepts by ref for lvalues and one which accepts by 
value for rvalues).

I would advise against ever using in. It's an alias for const scope, and scope 
is not currently fully implemented. scope is intended to disallow escaping 
from the function. So, with a non-reference type, using scope is pointless. 
And with a reference type, if/when scope is fully implemented later, you could 
end up with compilation errors because you _were_ escaping a scope parameter 
(e.g. by returning it or by assigning it to a static variable). At present, 
scope is at least partially implemented with delegates, but that's it. So, I'd 
advise against using scope (and thus in) with anything other than delegates. 
The primary benefit of using it with delegates is it allows the compiler to 
avoid allocating a closure when the function is called.

> > 'in' is nothing but 'scope const' (scope is not implemented yet):
> Does that mean "this is const within the current scope"?
> 
> And does "in" *not* guarantee that the object is *not* copied? I mean,
> if a parameter input to a function is read-only, it makes optimization
> sense to not copy it but just automatically provide a reference to it
> right? So I would expect in to mean const ref -- doesn't it work that
> way, and if not, why not?

in most definitely does _not_ guarantee that the object is not copied. Quite 
the opposite. It's an alias for const scope. If you want to avoid the copy, 
you need to use ref. in meant something slightly different in D1, and it was 
kept around for D2 but with the differences in the type system between them, it 
was decided to make it an alias for const scope. Personally, I wish that it 
was just gotten rid of outright due to the issues with scope and the confusion 
that it causes when people want to know what in does, but I guess that they 
wanted to reduce how much code broke when porting from D1 to D2.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list