On Thursday, 24 July 2014 at 11:39:13 UTC, Manu via Digitalmars-d
wrote:
On 24 July 2014 21:30, Manu <[email protected]> wrote:
On 24 July 2014 21:25, Manu <[email protected]> wrote:
On 24 July 2014 19:37, John Colvin via Digitalmars-d <
[email protected]> 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.