Why can't templates with default arguments be instantiated without the bang syntax?

2011-09-15 Thread Andrej Mitrovic
struct Foo(T = int) {}

void main()
{
Foo foo;  // fail
Foo!() bar;  // ok
}

It would be very convenient to be able to default to one type like this.

For example, in CairoD there's a Point structure which takes doubles
as its storage type, and then there's PointInt that takes ints. The
reason they're not both a template Point() that takes a type argument
is because in most cases the user will use the Point structure with
doubles, and only in rare cases Point with ints. So to simplify code
one doesn't have to write Point!double in all of their code, but
simply Point.

If the bang syntax wasn't required in presence of default arguments
then these workarounds wouldn't be needed.


Re: Why can't templates with default arguments be instantiated without the bang syntax?

2011-09-15 Thread Simen Kjaeraas
On Thu, 15 Sep 2011 16:46:24 +0200, Andrej Mitrovic  
andrej.mitrov...@gmail.com wrote:



struct Foo(T = int) {}

void main()
{
Foo foo;  // fail
Foo!() bar;  // ok
}

It would be very convenient to be able to default to one type like this.

For example, in CairoD there's a Point structure which takes doubles
as its storage type, and then there's PointInt that takes ints. The
reason they're not both a template Point() that takes a type argument
is because in most cases the user will use the Point structure with
doubles, and only in rare cases Point with ints. So to simplify code
one doesn't have to write Point!double in all of their code, but
simply Point.

If the bang syntax wasn't required in presence of default arguments
then these workarounds wouldn't be needed.


How would you then pass a single-argument template as a template alias
parameter?

Example:

template Foo( ) {
template Bar( ) {
}
}

template Baz(alias A) {
mixin A!();
}

void main( ) {
mixin Baz!Foo;
}

Does this mixin Foo or Bar to main's scope?

--
  Simen


Re: Why can't templates with default arguments be instantiated without the bang syntax?

2011-09-15 Thread Christophe
Simen Kjaeraas , dans le message (digitalmars.D.learn:29539), a
 écrit :
 On Thu, 15 Sep 2011 16:46:24 +0200, Andrej Mitrovic  
 andrej.mitrov...@gmail.com wrote:
 
 struct Foo(T = int) {}

 void main()
 {
 Foo foo;  // fail
 Foo!() bar;  // ok
 }

 It would be very convenient to be able to default to one type like this.

 For example, in CairoD there's a Point structure which takes doubles
 as its storage type, and then there's PointInt that takes ints. The
 reason they're not both a template Point() that takes a type argument
 is because in most cases the user will use the Point structure with
 doubles, and only in rare cases Point with ints. So to simplify code
 one doesn't have to write Point!double in all of their code, but
 simply Point.

 If the bang syntax wasn't required in presence of default arguments
 then these workarounds wouldn't be needed.
 
 How would you then pass a single-argument template as a template alias
 parameter?
 
 Example:
 
 template Foo( ) {
  template Bar( ) {
  }
 }
 
 template Baz(alias A) {
  mixin A!();
 }
 
 void main( ) {
  mixin Baz!Foo;
 }
 
 Does this mixin Foo or Bar to main's scope?

I don't get the problem. Maybe I am not used to mixin enough. Can you 
mixin normal templates, and not only mixin templates ?

Anyway, why would this mixin Bar ?
As I understand the proposition, only mixin Baz!(Foo.Bar); and of 
course mixin Baz!(Foo!().Bar) should mixin Bar.

-- 
Christophe


Re: Why can't templates with default arguments be instantiated without the bang syntax?

2011-09-15 Thread Jonathan M Davis
On Thursday, September 15, 2011 16:46:24 Andrej Mitrovic wrote:
 struct Foo(T = int) {}
 
 void main()
 {
 Foo foo;  // fail
 Foo!() bar;  // ok
 }
 
 It would be very convenient to be able to default to one type like this.
 
 For example, in CairoD there's a Point structure which takes doubles
 as its storage type, and then there's PointInt that takes ints. The
 reason they're not both a template Point() that takes a type argument
 is because in most cases the user will use the Point structure with
 doubles, and only in rare cases Point with ints. So to simplify code
 one doesn't have to write Point!double in all of their code, but
 simply Point.
 
 If the bang syntax wasn't required in presence of default arguments
 then these workarounds wouldn't be needed.

There is no type inference for templated structs, so you need the bang. Only 
functions get type inference. They way to fix this is to create a separate 
factory function to construct the type. std.container does this with 
redBlackTree for RedBlackTree.

- Jonathan M Davis


Re: Why can't templates with default arguments be instantiated without the bang syntax?

2011-09-15 Thread Steven Schveighoffer
On Thu, 15 Sep 2011 10:46:24 -0400, Andrej Mitrovic  
andrej.mitrov...@gmail.com wrote:



struct Foo(T = int) {}

void main()
{
Foo foo;  // fail
Foo!() bar;  // ok
}

It would be very convenient to be able to default to one type like this.

For example, in CairoD there's a Point structure which takes doubles
as its storage type, and then there's PointInt that takes ints. The
reason they're not both a template Point() that takes a type argument
is because in most cases the user will use the Point structure with
doubles, and only in rare cases Point with ints. So to simplify code
one doesn't have to write Point!double in all of their code, but
simply Point.

If the bang syntax wasn't required in presence of default arguments
then these workarounds wouldn't be needed.


Perhaps a different approach:

struct PointT(T) {...}

alias PointT!(double) Point;

// and if so desired:

alias PointT!int PointInt;

Just a thought...

-Steve


Re: Why can't templates with default arguments be instantiated without the bang syntax?

2011-09-15 Thread Jacob Carlborg

On 2011-09-15 16:46, Andrej Mitrovic wrote:

struct Foo(T = int) {}

void main()
{
 Foo foo;  // fail
 Foo!() bar;  // ok
}

It would be very convenient to be able to default to one type like this.

For example, in CairoD there's a Point structure which takes doubles
as its storage type, and then there's PointInt that takes ints. The
reason they're not both a template Point() that takes a type argument
is because in most cases the user will use the Point structure with
doubles, and only in rare cases Point with ints. So to simplify code
one doesn't have to write Point!double in all of their code, but
simply Point.

If the bang syntax wasn't required in presence of default arguments
then these workarounds wouldn't be needed.


I've wondered the same thing, why this doesn't work:

template Foo (T = int) {}

mixin Foo;

But this works:

template Foo () {}

mixin Foo;

--
/Jacob Carlborg


Re: Why can't templates with default arguments be instantiated without the bang syntax?

2011-09-15 Thread Simen Kjaeraas
On Thu, 15 Sep 2011 17:54:19 +0200, Christophe  
trav...@phare.normalesup.org wrote:



Simen Kjaeraas , dans le message (digitalmars.D.learn:29539), a
 écrit :

On Thu, 15 Sep 2011 16:46:24 +0200, Andrej Mitrovic
andrej.mitrov...@gmail.com wrote:


struct Foo(T = int) {}

void main()
{
Foo foo;  // fail
Foo!() bar;  // ok
}

It would be very convenient to be able to default to one type like  
this.


For example, in CairoD there's a Point structure which takes doubles
as its storage type, and then there's PointInt that takes ints. The
reason they're not both a template Point() that takes a type argument
is because in most cases the user will use the Point structure with
doubles, and only in rare cases Point with ints. So to simplify code
one doesn't have to write Point!double in all of their code, but
simply Point.

If the bang syntax wasn't required in presence of default arguments
then these workarounds wouldn't be needed.


How would you then pass a single-argument template as a template alias
parameter?

Example:

template Foo( ) {
 template Bar( ) {
 }
}

template Baz(alias A) {
 mixin A!();
}

void main( ) {
 mixin Baz!Foo;
}

Does this mixin Foo or Bar to main's scope?


I don't get the problem. Maybe I am not used to mixin enough. Can you
mixin normal templates, and not only mixin templates ?

Anyway, why would this mixin Bar ?
As I understand the proposition, only mixin Baz!(Foo.Bar); and of
course mixin Baz!(Foo!().Bar) should mixin Bar.


Sorry, you're right. I meant:

template Foo( ) {
template Foo( ) {
}
}

--
  Simen