Template argument deduction and default args

John Colvin via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 24 05:03:29 PDT 2014


On Thursday, 24 July 2014 at 11:39:13 UTC, Manu via Digitalmars-d 
wrote:
> On 24 July 2014 21:30, Manu <turkeyman at gmail.com> wrote:
>
>> On 24 July 2014 21:25, Manu <turkeyman at gmail.com> wrote:
>>
>>> On 24 July 2014 19:37, John Colvin via Digitalmars-d <
>>> digitalmars-d at puremagic.com> wrote:
>>>
>>>> On Thursday, 24 July 2014 at 04:53:41 UTC, Manu via 
>>>> Digitalmars-d wrote:
>>>>
>>>>> I'm running into consistent problems with default args and 
>>>>> argument
>>>>> deduction in templates.
>>>>> There seem to be 2 consistent classes of problem:
>>>>>
>>>>> struct S(size_t len = 10)
>>>>> {
>>>>>   ubyte[len] data;
>>>>> }
>>>>>
>>>>> S!100 x; // this works fine
>>>>> S y; // this doesn't work (!)
>>>>> S!() z; // this works
>>>>>
>>>>> The template arg has a default arg, why require !() ??
>>>>> This causes problems in meta code, where you want to create 
>>>>> an instance
>>>>> of
>>>>> some T, and T may be a normal type with no template args, 
>>>>> in which case
>>>>> !()
>>>>> is invalid, but a template type with default args should 
>>>>> also be
>>>>> acceptable, but it doesn't work because the meta code 
>>>>> doesn't specify
>>>>> !().
>>>>>
>>>>
>>>> This opens a whole can of worms. It's very useful to be able 
>>>> to
>>>> distinguish between templates and their instantiations. 
>>>> Seeing as D's alias
>>>> system works on a pass-by-name system, you can't have a 
>>>> system where simply
>>>> referring to a template instantiates it with no arguments.
>>>>
>>>> Apart from anything else it would break *so* much code.
>>>>
>>>
>>> Isn't the call to the constructor enough to distinguish it is 
>>> an
>>> instantiation rather than a reference to the template itself?
>>>
>>> S is a template
>>> S!() is a type
>>> S(x,y,z) is a call to it's constructor, the expression has a 
>>> type
>>>
>>>  What is the useful distinction between S!()(x,y,z) and 
>>> S(x,y,z)? How
>>> does either one of them make referring to the template 'S' 
>>> difficult?
>>> Is there some conflicting syntax where the parentheses mean 
>>> something
>>> else when S perceived as a template? Why isn't the same 
>>> problem applicable
>>> to function templates?
>>>
>>
>> Ack! Sorry! I misread, your response as being related to the 
>> constructor
>> case, not the default arg case >_<
>>
>> I see the problem with the default arg case. It's a real 
>> shame, because it
>> has rather annoying side effects in generic code, and it 
>> doesn't appear to
>> follow the same logical rules as with functions.
>> This is precisely the sort of thing Scott Myers would be 
>> unhappy about...
>> Someone will need to 'explain' this for years to come, I don't 
>> think it's
>> intuitive ;)
>>
>
> Although... the more I think about it, the more I wonder why it 
> matters if
> the syntax is ambiguous when the name is taken in isolation, 
> that never
> actually happens...
> Why can't it just mean 'either the template, or the default arg
> instantiation', and be resolved when it's actually used?
> Is it possible for templates or types to both appear in the 
> same context
> and create an actual ambiguity? What would that expression look 
> like?
> The only place I can imagine a conflict could occur would be 
> within an is()
> expression, but I'm not sure... can a uninstantiated template 
> be used in an
> is() expression where a type would also be a meaningful fit?
>
> Generally, templates do this:
>   T!()
> And types do this:
>   T var;
>
> It's clear syntactically from 'T!()' that T is not a default 
> args
> instantiation of T, because it's involved in a template 
> instantiation
> expression.
> It's also clear from 'T var' that T is not a template, because 
> a variable
> needs to have a type.

Seeing as templates can resolve to other templates, mixin 
templates, values, functions and types, the situation is 
complicated.


More information about the Digitalmars-d mailing list