On Thursday, 8 November 2012 at 18:28:44 UTC, Dmitry Olshansky wrote:
What's wrong with going this route:

void blah(auto ref X stuff){
...lots of code...
}

is magically expanded to:

void blah(ref X stuff){
...that code..
}

and

void blah(X stuff){
.blah(stuff); //now here stuff is L-value so use the ref version
}

Yeah, it looks _almost_ like a template now. But unlike with a template we can assume it's 2 overloads _always_. External fucntion issue is then solved by treating it as exactly these 2 overloads (one trampoline, one real). Basically it becomes one-line declaration of 2 functions.

Given that temporaries are moved anyway the speed should be fine and there is as much bloat as you'd do by hand.

Also hopefully inliner can be counted on to do its thing in this simple case.

That second overload for rvalues would be a shortcut to save the lvalue declarations at each call site - and it really doesn't matter if the compiler magically added the lvalue declarations before each call or if it magically added the rvalue overload (assuming all calls are inlined). But it would create a problem if there already was an explicit 'void blah(X)' overload in addition to 'void blah(auto ref X)' (not making much sense obviously, but this would be something the compiler needed to handle somehow). What this 'auto ref' approach (both as currently implemented for templates and proposed here for non-templated functions) lacks is the vital distinction between const and mutable parameters.

For the much more common const ref parameters, I repeatedly tried to explain why I'm absolutely convinced that we don't need another keyword and that 'in/const ref' is sufficient, safe, logical and intuitive (coupled with the overload rule that pass-by-value (moving) is preferred for rvalues). Please prove me wrong.

For the less common mutable ref parameters, I also repeatedly tried to explain why I find it dangerous/unsafe to allow rvalues to be bound to mutable ref parameters. But if there are enough people wanting that, I'd have no problem with an 'auto ref' approach for it (only for mutable parameters!). That may actually be a good compromise, what do you guys think? :)

'auto ref T' for templates expands to 'ref T' (lvalues) and 'T' (rvalues), duplicating the whole function and providing best performance - no pointer/reference indirection for rvalues in contrast to 'auto ref T' (proposed above) for non-templates, otherwise the concept would be exactly the same. But it's only for mutable parameters. Such a templated option may also be worth for const parameters though (expanding to 'const ref T' and 'const T'), so maybe something like the (ambiguous) 'in/const auto ref T' wouldn't actually be that bad (assuming there are only a few use cases, and only for templates! It'd still be 'in ref T' for non-templates).

Reply via email to