"Best" way of passing in a big struct to a function?

Jonathan M Davis jmdavisProg at gmx.com
Tue Oct 9 21:47:36 PDT 2012


On Wednesday, October 10, 2012 06:27:52 Val Markovic wrote:
> TL;DR: what should I use if I need C++'s const& for a param?
> 
> Long version: I have a big struct provided by a library and I'm
> trying to pass instances of it to a function that will never need
> to modify the passed in value. Naturally I want to pass it
> efficiently, without incurring a copy. I know that I can use
> "const ref" in D, but is this the preferred way of doing it? How
> about "in ref"? Or something else?
> 
> Related background: I'm a D newbie, I've read TDPL and I loved it
> and I'm now working on a Markdown processor as a D learning
> exercise. I've written hundreds of thousands of C++ LOC and this
> is the perspective from which I look at D (and I love what I see).

Unlike in C++, const ref in D requires that the argument be an lvalue just 
like with ref, so if you define const ref, it won't work with rvalues. You'd 
need to create an overload which wasn't ref to do that. e.g.

auto foo(const S s)
{
    return foo(s);
}

auto foo(const ref S s)
{
    ...
}

And if you do that, make sure that the constness of the functions matches, or 
you'll get infinite recursion, because the constness gets matched before the 
refness of the type when the overload is selected when calling the function.

If your function is templated, then you can use auto ref

auto foo(S)(auto ref S s)
{
    ...
}

or

auto foo(S)(auto ref const S s)
{
    ...
}

If you want the function templated (to be able to use auto ref) but not its 
arguments, then do

auto foo()(auto ref const S s)
{
    ...
}

auto ref does essentially the same as the first example, but the compiler 
generates the overloads for you. But again, it only works with templated 
functions.

This whole topic is a bit of a thorny one in that D's design is trying to 
avoid some of the problems that allowing const T& to take rvalues in C++ 
causes, but it makes a situation like what you're trying to do annoying to 
handle. And auto ref doesn't really fix it (even though that's whole the reason 
that it was added), because it only works with templated functions. There have 
been some discussions on how to adjust how ref works in order to fix the 
problem without introducing the problems that C++ has with it, but nothing has 
actually be decided on yet, let alone implemented.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list