December 25, 2012
On Tuesday, December 25, 2012 11:14:40 Namespace wrote:
> > What does this generate?
> > 
> > auto foo(auto ref S a, auto ref S b, auto ref S c, auto ref S
> > d) { ... }
> > 
> > 16 different functions, one for each combination? Sounds like a bad idea.
> 
> In my opinion, this should produce only two functions:
> #1: auto foo(ref S a, ref S b, ref S c, ref S d) { ... }
> #2: auto foo(S a, S b, S c, S d) { ... }

So, you'd take the performance hit of copying all of your function arguments simply because one of them was an rvalue?

No. I think that Peter's point shows exactly why this is a bad idea.

However, creating only one version of the function which takes all refs and specifcally creating variables underneath the hood for any rvalues so that they can be passed to the function still seems like it could work.

- Jonathan M Davis
December 25, 2012
On Tuesday, December 25, 2012 11:12:43 Jens Mueller wrote:
> Jonathan M Davis wrote:
> > On Tuesday, December 25, 2012 01:56:42 Peter Alexander wrote:
> > > On Monday, 24 December 2012 at 17:40:54 UTC, Jonathan M Davis
> > > 
> > > wrote:
> > > > Why can't we simply make auto ref work with non-templated
> > > > functions by making
> > > > it automatically generate both the ref and non-ref versions?
> > > > 
> > > > [snip]
> > > > 
> > > > What problems does this cause? Why haven't we just done this already?
> > > 
> > > What does this generate?
> > > 
> > > auto foo(auto ref S a, auto ref S b, auto ref S c, auto ref S d)
> > > { ... }
> > > 
> > > 16 different functions, one for each combination? Sounds like a bad idea.
> > 
> > Excellent point.
> 
> I'm not sure but doesn't the compiler only create such a function when
> it is called.
> Still it may be confusing but it's similar to a function template. But
> here it's a template regarding passing convention.

If it were a template, sure. But the whole point is that we need a solution which _isn't_ a template, which in this case would mean generating every possible combination regardless of whether they were used or not. So, I think that Peter has shown why that particular approach is untenable.

- Jonathan M Davis
December 25, 2012
Jonathan M Davis wrote:
> On Tuesday, December 25, 2012 11:12:43 Jens Mueller wrote:
> > Jonathan M Davis wrote:
> > > On Tuesday, December 25, 2012 01:56:42 Peter Alexander wrote:
> > > > On Monday, 24 December 2012 at 17:40:54 UTC, Jonathan M Davis
> > > > 
> > > > wrote:
> > > > > Why can't we simply make auto ref work with non-templated
> > > > > functions by making
> > > > > it automatically generate both the ref and non-ref versions?
> > > > > 
> > > > > [snip]
> > > > > 
> > > > > What problems does this cause? Why haven't we just done this already?
> > > > 
> > > > What does this generate?
> > > > 
> > > > auto foo(auto ref S a, auto ref S b, auto ref S c, auto ref S d)
> > > > { ... }
> > > > 
> > > > 16 different functions, one for each combination? Sounds like a bad idea.
> > > 
> > > Excellent point.
> > 
> > I'm not sure but doesn't the compiler only create such a function when
> > it is called.
> > Still it may be confusing but it's similar to a function template. But
> > here it's a template regarding passing convention.
> 
> If it were a template, sure. But the whole point is that we need a solution which _isn't_ a template, which in this case would mean generating every possible combination regardless of whether they were used or not. So, I think that Peter has shown why that particular approach is untenable.

And the solution needs to be non-template based because it needs to work with classes? Is that the only reason?

Jens
December 25, 2012
On Tuesday, December 25, 2012 11:44:45 Jens Mueller wrote:
> And the solution needs to be non-template based because it needs to work with classes? Is that the only reason?

That and if it's not non-templated, it's impossible to have auto ref functions which hide their implementation for those who need to use .di files to hide the implementation. It also might also be necessary if you need to be able to guarantee that the function exists. Basically, any situation where you can't use a template or where it's undesirable to use a template, the current auto ref doesn't work. But the big one is classes, as templated functions can't be virtual. Without a non-templated solution, virtual functions will never be able to do the equivalent of C++'s const& or anything like it, meaning that they'll incur overhead due to unnecessary copies in many cases.

- Jonathan M Davis
December 25, 2012
On 12/25/12 12:34 AM, Zhenya wrote:
> On Tuesday, 25 December 2012 at 01:40:16 UTC, Peter Alexander wrote:
>> On Tuesday, 25 December 2012 at 00:56:44 UTC, Peter Alexander wrote:
>>> On Monday, 24 December 2012 at 17:40:54 UTC, Jonathan M Davis wrote:
>>>> And if that doesn't work, can we simply make it so that the compiler
>>>> automatically creates a variable when you pass an rvalue to a
>>>> non-templated
>>>> auto ref function?
>>>
>>> I don't see any problems with this, but I admittedly haven't thought
>>> too much about it.
>>
>> If there are no problems with this way, then what I want to know is
>> why the template version of auto ref wasn't implemented this way. The
>> way auto ref is currently implemented for templates is a bit of a mess.
> Maybe it's difficult to generate both versions because for the function
> like this
>
> void foo(auto ref S s1,auto ref S s2,...,auto ref s10)
>
> compiler should generate 2^10 versions of function foo.

The compiler will only generate as many versions as there are compatible calls.

Andrei
December 25, 2012
On 12/25/12 5:36 AM, Jonathan M Davis wrote:
> On Tuesday, December 25, 2012 11:14:40 Namespace wrote:
>>> What does this generate?
>>>
>>> auto foo(auto ref S a, auto ref S b, auto ref S c, auto ref S
>>> d) { ... }
>>>
>>> 16 different functions, one for each combination? Sounds like a
>>> bad idea.
>>
>> In my opinion, this should produce only two functions:
>> #1: auto foo(ref S a, ref S b, ref S c, ref S d) { ... }
>> #2: auto foo(S a, S b, S c, S d) { ... }
>
> So, you'd take the performance hit of copying all of your function arguments
> simply because one of them was an rvalue?
>
> No. I think that Peter's point shows exactly why this is a bad idea.
>
> However, creating only one version of the function which takes all refs and
> specifcally creating variables underneath the hood for any rvalues so that
> they can be passed to the function still seems like it could work.

Yes, that does work and is easy to implement.

Andrei

December 25, 2012
On Tuesday, 25 December 2012 at 14:09:13 UTC, Andrei Alexandrescu wrote:
> On 12/25/12 12:34 AM, Zhenya wrote:
>> On Tuesday, 25 December 2012 at 01:40:16 UTC, Peter Alexander wrote:
>>> On Tuesday, 25 December 2012 at 00:56:44 UTC, Peter Alexander wrote:
>>>> On Monday, 24 December 2012 at 17:40:54 UTC, Jonathan M Davis wrote:
>>>>> And if that doesn't work, can we simply make it so that the compiler
>>>>> automatically creates a variable when you pass an rvalue to a
>>>>> non-templated
>>>>> auto ref function?
>>>>
>>>> I don't see any problems with this, but I admittedly haven't thought
>>>> too much about it.
>>>
>>> If there are no problems with this way, then what I want to know is
>>> why the template version of auto ref wasn't implemented this way. The
>>> way auto ref is currently implemented for templates is a bit of a mess.
>> Maybe it's difficult to generate both versions because for the function
>> like this
>>
>> void foo(auto ref S s1,auto ref S s2,...,auto ref s10)
>>
>> compiler should generate 2^10 versions of function foo.
>
> The compiler will only generate as many versions as there are compatible calls.

If it were a template. Jonathan's (first) proposal is that they are all generated eagerly, so that they can be used as virtual functions (among other things). Generating them lazily like template defeats the purpose of his proposal (to do that, just use templates!)

The first proposal is a dead end. I think his second proposal is more interesting, so I will repeat it here:

"Can we simply make it so that the compiler automatically creates a variable when you pass an rvalue to a non-templated auto ref function?"

So non-template auto ref parameters are just like ref parameters, except they will automatically convert rvalues to lvalues on call by creating a local variable. Normal ref parameters will still need lvalues.
December 25, 2012
On Tuesday, 25 December 2012 at 14:11:14 UTC, Andrei Alexandrescu wrote:
> On 12/25/12 5:36 AM, Jonathan M Davis wrote:
>> However, creating only one version of the function which takes all refs and
>> specifcally creating variables underneath the hood for any rvalues so that
>> they can be passed to the function still seems like it could work.
>
> Yes, that does work and is easy to implement.

Is there any reason this hasn't been implemented? And why aren't template auto ref functions implemented like that? It would be a bit of a shame if auto ref in template functions works differently to auto ref in non-template function.
December 25, 2012
12/25/2012 6:15 PM, Peter Alexander пишет:
> On Tuesday, 25 December 2012 at 14:09:13 UTC, Andrei Alexandrescu wrote:
[snip]
>>>
>>> void foo(auto ref S s1,auto ref S s2,...,auto ref s10)
>>>
>>> compiler should generate 2^10 versions of function foo.
>>
>> The compiler will only generate as many versions as there are
>> compatible calls.
>
> If it were a template. Jonathan's (first) proposal is that they are all
> generated eagerly, so that they can be used as virtual functions (among
> other things). Generating them lazily like template defeats the purpose
> of his proposal (to do that, just use templates!)
>
> The first proposal is a dead end. I think his second proposal is more
> interesting, so I will repeat it here:
>
> "Can we simply make it so that the compiler automatically creates a
> variable when you pass an rvalue to a non-templated auto ref function?"
>
> So non-template auto ref parameters are just like ref parameters, except
> they will automatically convert rvalues to lvalues on call by creating a
> local variable. Normal ref parameters will still need lvalues.

+1
I think that was pretty much the conclusion of the last ref-to-rvalue thread. Just make sure proper scoping rules are followed.


-- 
Dmitry Olshansky
December 26, 2012
On 2012-12-25 15:11, Andrei Alexandrescu wrote:

> Yes, that does work and is easy to implement.

That's also what one needs to do now.

-- 
/Jacob Carlborg