April 15, 2013
On Mon, 15 Apr 2013 13:21:52 -0400, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 04/15/2013 05:18 PM, Steven Schveighoffer wrote:
>> On Sun, 14 Apr 2013 11:47:47 -0400, Timon Gehr <timon.gehr@gmx.ch> wrote:
>>
>>> On 04/13/2013 01:00 AM, bearophile wrote:
>>>> This is one of the few C++14 core language proposals that seem
>>>> interesting for D:
>>>>
>>>> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3602.html
>>>>
>>>> The purpose of this idea is to avoid the helper functions that are
>>>> currently used in D to build template structs/classes. Even if this
>>>> feature is restricted to only a subset of all the templated
>>>> structs/classes it seems useful to avoid some boilerplate code.
>>>>
>>>> Is this idea adaptable to D?
>>>>
>>>> Bye,
>>>> bearophile
>>>
>>> I think the differences to be accounted for are basically that D has
>>> n-ary default constructors, static opCall, and static if. Furthermore,
>>> with IFTI, it is possible to only specify the prefix of the template
>>> arguments.
>>>
>>> ---
>>>
>>> struct S(T...){
>>>      T data;
>>> }
>>>
>>> S(1,2,3); // ?
>>
>> Should work.  The implicit default constructor should be treated as a
>> function.
>>
>
> It cannot be treated exactly like a function because it depends on the struct layout. It is very well possible that the struct layout cannot be easily determined without instantiation. The example below demonstrates that it is not entirely obvious.

I am not very well-versed in exactly how the compiler is implemented, but to me, the above is not much different than:

struct S(T...){
    T data;
}

S(T...) makeS(T...)(T data) { return S!T(data);}

If the compiler can examine makeS enough to figure out how to instantiate makeS, then why can't it figure out how to instantiate S directly?

>>> ...
>>>
>>> ---
>>>
>>> struct S(T...){
>>>      T data;
>>>      static if(T.length){
>>>          this(T x){ }
>>>      }
>>> }
>>>
>>> S(1,2,3); // ?
>>
>> I think this should follow IFTI rules.  If this is allowed:
>>
>> template foo(T...) {
>>     static if(T.length)
>>        void foo(T x) {}
>> }
>
> This probably shouldn't be allowed because a compiler cannot satisfy arbitrary expressions.

Then if that cannot be allowed, the struct cannot be allowed.

>>
>> Then the struct should be allowed as well.
>>
>
> It is more subtle than that. The layout of S begins with T data. Does this mean S(1,2,3) instantiates to S!(int,int,int)(1,2,3), as above ? When does this happen? Is it checked that the constructor used for guessing the parameters is the constructor that gets called?

I predicated this statement on the condition that IFTI allows it.  If that isn't true, then it makes no sense for structs to be able to allow it.

I'm going on the principal that IFTI allows "external" constructors of the same form.  I view it as a kind of lowering.  But it only works if the compiler can figure out the struct layout without binding the exact types.  Basically, it must be able to examine the constructor and/or variable layout in order to imply the appropriate constructor function parameters.

I also realize that this complicates IFTI, since it currently requires that nothing but the function declaration be inside the template.  IFTI will have to be more complex in order for this to work.

> Also: What happens if there is more than one constructor?

More than one constructor can work, it depends on how the constructor is specified.

For example:

struct S(T)
{
   this(T t) {}
   this(T t, string s) {}
}

seems fine to me.  Again, it requires upgrades to IFTI.

-Steve
1 2
Next ›   Last »