On Thursday, 24 July 2014 at 11:25:28 UTC, Manu via Digitalmars-d 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?

That's a somewhat different consideration.

I agree that this working might be a good thing:

struct S(int n = 10)
{
    int a;
}

auto s = S(4);

where the type of the struct does not depend on the type of the parameters to the constructor. However, I'm not sold that full-on implicit template instantiation should apply to members. How would we deal with this situation:

struct S(T)
{
    this(T v) {}
}

auto s = S(4); //yay, compiler worked out S!int

later on someone does this:

struct S(T)
{
    this(Q v) if(is(Q : T)) {}
}

for whatever reason.

Now all those nice constructor calls to S(someValue) are broken.

I dunno, somehow the implicit behaviour seems ok when it's very local but it feels dodgy at the level of separation that there can be between constructors and their types.

Reply via email to