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