Re: Template argument deduction not working with template specialization

2021-01-17 Thread Paul via Digitalmars-d-learn
I just figured out half of my frustration is caused by a 
collision between the 'alias this'd template possibillity and the 
normal one.

For example:


struct Bar(uint size, V) {
V[size] blup;
alias blup this;
}

void foo(S : T[], T)(S a) {
pragma(msg, "first");
}

void foo(S : Bar!(T, U), uint T, U)(S a) {
pragma(msg, "second");
}



Bar!(2, int) bar;
foo(bar);


Will cause "called with argument types `(Bar!(2u, int))` matches 
both:DUB"
(And "undefined identifier `T`DUB", "undefined identifier 
`U`DUB", but thats a false positive :/)
While removal of either will make it work fine, as would removal 
of the alias.


Templating:
The template picked to instantiate is the one that is most 
specialized that fits the types of the TemplateArgumentList.

Alias this:
If an aggregate declaration defines an opCmp or opEquals 
method, it will take precedence to that of the aliased this 
member.


I was of the impression D only defaulted to the alias when the 
original implementation of a (member) function was missing / 
disfunctional. Shouldn't aliasing also follow this logic when 
using template specializations? (Even though it may not be a 
member function)


Re: Template argument deduction not working with template specialization

2021-01-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/17/21 3:41 PM, Paul wrote:

On Sunday, 17 January 2021 at 16:42:27 UTC, Steven Schveighoffer wrote:



This works:

void TFoo(T : U[], U)(T a)


Oh cool, that's surprising to say the least. Thanks! This indeed works 
with argument deduction :)


It's basically saying if T matches the pattern U[] for some U (which is 
actually defined now inside the function), then it's a match (and 
preferred over the non-specialized template).


-Steve


Re: Template argument deduction not working with template specialization

2021-01-17 Thread Paul via Digitalmars-d-learn
On Sunday, 17 January 2021 at 16:42:27 UTC, Steven Schveighoffer 
wrote:
I've always hated that aspect of specialization. I don't really 
understand why it's valid (how can T be T[]?)


I totally agree with that, that confuses me as well.


This works:

void TFoo(T : U[], U)(T a)


Oh cool, that's surprising to say the least. Thanks! This indeed 
works with argument deduction :)


Re: Template argument deduction not working with template specialization

2021-01-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/17/21 11:22 AM, Paul wrote:
While trying to use template specializations I noticed the argument 
deductions do not yield the same version as the ones yielded when being 
explicit.

Example:


uint a = 1;
uint[] b = [2];
TFoo(a);
TFoo!(uint[])(b);



void TFoo(T)(T a) {
pragma(msg, "T: " ~ T.stringof);
}

void TFoo(T : T[])(T[] a) {
pragma(msg, "T[]: " ~ T.stringof);
}


I noticed that an automatically deduced TFoo call always yields the 
first, while TFoo!(uint[]) yields the array version if present, and 
defaults to the first elsewise.


Am I incorrect in expecting the same behavior when (ab)using argument 
deduction or does my usage make sense? I tried searching for this 
combination (deduction & specialization) but couldn't find another forum 
post / documentation example.


I've always hated that aspect of specialization. I don't really 
understand why it's valid (how can T be T[]?)


This works:

void TFoo(T : U[], U)(T a)

-Steve


Template argument deduction not working with template specialization

2021-01-17 Thread Paul via Digitalmars-d-learn
While trying to use template specializations I noticed the 
argument deductions do not yield the same version as the ones 
yielded when being explicit.

Example:


uint a = 1;
uint[] b = [2];
TFoo(a);
TFoo!(uint[])(b);



void TFoo(T)(T a) {
pragma(msg, "T: " ~ T.stringof);
}

void TFoo(T : T[])(T[] a) {
pragma(msg, "T[]: " ~ T.stringof);
}


I noticed that an automatically deduced TFoo call always yields 
the first, while TFoo!(uint[]) yields the array version if 
present, and defaults to the first elsewise.


Am I incorrect in expecting the same behavior when (ab)using 
argument deduction or does my usage make sense? I tried searching 
for this combination (deduction & specialization) but couldn't 
find another forum post / documentation example.


Re: Template argument deduction fails with alias

2020-09-01 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 1 September 2020 at 02:48:08 UTC, Ben Jones wrote:


Thanks all.

I tried using alias this at first and then I get errors trying 
to construct AliasType objects:



auto pi = Payload!int(5);
auto pe = ParseError("error");
alias PRType = ParseResult!(Payload!int, ParseError);
auto pr = PRType(pi);

gives:

cannot implicitly convert expression `pi` of type `Payload!int` 
to `SumType!(Payload!int, ParseError)`


Unfortunately, `alias this` does not apply to constructors. You 
can either add your own constructor to the wrapper struct:


struct ParseResult(Ts...)
{
SumType!Ts data;
alias data this;

this(T)(T t)
if (staticIndexOf!(T, data.Types) >= 0)
{
data = t;
}
}

...or use a factory function like the following:

PRType parseResult(T)(T t)
{
return PRType(SumType!(Payload!int, ParseError)(t));
}


Re: Template argument deduction fails with alias

2020-08-31 Thread Ben Jones via Digitalmars-d-learn

On Tuesday, 1 September 2020 at 01:26:30 UTC, Paul Backus wrote:



Aside from using SumType directly in the function signature, 
another workaround is to use a wrapper struct instead of an 
alias:


struct AliasType(Args...) {
SumType!Args data;
alias data this;
}

bool func(T : AliasType!Args, Args...)(T t) { ... }


Thanks all.

I tried using alias this at first and then I get errors trying to 
construct AliasType objects:



auto pi = Payload!int(5);
auto pe = ParseError("error");
alias PRType = ParseResult!(Payload!int, ParseError);
auto pr = PRType(pi);

gives:

cannot implicitly convert expression `pi` of type `Payload!int` 
to `SumType!(Payload!int, ParseError)`







Re: Template argument deduction fails with alias

2020-08-31 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 1 September 2020 at 01:11:35 UTC, Ben Jones wrote:

I have an alias that looks like

static if(...){
  alias AliasType = SumType!(...);
}

which I use in a template constraint for a function template:

bool func(T: AliasType!Args, Args...)(T t){ ... }


When I try to call func with an AliasType object, the argument 
deduction fails with a message saying that the argument type (a 
SumType) doesn't match the template constraint (an AliasType)


Things do work if I change the template constraint to be a 
SumType rather an an AliasType


Is there a workaround to this?  Here's a complete example: 
https://run.dlang.io/is/buRGTs


This is a very old known bug:

https://issues.dlang.org/show_bug.cgi?id=1807

Attempts have been made to fix it, but the problem is a lot more 
complicated than it looks at first glance, so I wouldn't expect a 
solution any time soon.


Aside from using SumType directly in the function signature, 
another workaround is to use a wrapper struct instead of an alias:


struct AliasType(Args...) {
SumType!Args data;
alias data this;
}

bool func(T : AliasType!Args, Args...)(T t) { ... }


Re: Template argument deduction fails with alias

2020-08-31 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/31/20 9:11 PM, Ben Jones wrote:

I have an alias that looks like

static if(...){
   alias AliasType = SumType!(...);
}

which I use in a template constraint for a function template:

bool func(T: AliasType!Args, Args...)(T t){ ... }


When I try to call func with an AliasType object, the argument deduction 
fails with a message saying that the argument type (a SumType) doesn't 
match the template constraint (an AliasType)


Things do work if I change the template constraint to be a SumType 
rather an an AliasType


Is there a workaround to this?  Here's a complete example: 
https://run.dlang.io/is/buRGTs




Very old enhancement request (I doubt this will ever happen): 
https://issues.dlang.org/show_bug.cgi?id=1807


-Steve


Template argument deduction fails with alias

2020-08-31 Thread Ben Jones via Digitalmars-d-learn

I have an alias that looks like

static if(...){
  alias AliasType = SumType!(...);
}

which I use in a template constraint for a function template:

bool func(T: AliasType!Args, Args...)(T t){ ... }


When I try to call func with an AliasType object, the argument 
deduction fails with a message saying that the argument type (a 
SumType) doesn't match the template constraint (an AliasType)


Things do work if I change the template constraint to be a 
SumType rather an an AliasType


Is there a workaround to this?  Here's a complete example: 
https://run.dlang.io/is/buRGTs




Re: Function template argument deduction

2018-04-07 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 7 April 2018 at 14:02:55 UTC, Paul Backus wrote:
Interesting. Looks like this is an issue with aliases, because 
I get the error with this code too:


--- test.d
import std.typecons: Tuple, tuple;

alias Pair(T) = Tuple!(T, T);

void foo(T)(Pair!T p)
{
return;
}

unittest {
Pair!int x = tuple(1, 2);
foo(x);
}
---


Looks like this is the same problem described in issue 1807:

https://issues.dlang.org/show_bug.cgi?id=1807

I'm not sure what D was like when Martin Nowak made the most 
recent comment on that issue, in 2012, but alias templates do 
have their own dedicated language construct now, so maybe this is 
worth revisiting.


Re: Function template argument deduction

2018-04-07 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 7 April 2018 at 06:26:24 UTC, Uknown wrote:

What I did notice though is that when
`string list2string(T)(List!T list)` was changed to
`string list2string(T)(VariantN!(16LU, Nil, Tuple!(T, "head", 
This*, "tail")) list)`

The compiler correctly deduce `T` to be `int`


Interesting. Looks like this is an issue with aliases, because I 
get the error with this code too:


--- test.d
import std.typecons: Tuple, tuple;

alias Pair(T) = Tuple!(T, T);

void foo(T)(Pair!T p)
{
return;
}

unittest {
Pair!int x = tuple(1, 2);
foo(x);
}
---


Re: Function template argument deduction

2018-04-06 Thread Ali Çehreli via Digitalmars-d-learn

On 04/06/2018 11:26 PM, Uknown wrote:
> On Saturday, 7 April 2018 at 05:58:10 UTC, Paul Backus wrote:
>> On Saturday, 7 April 2018 at 05:46:07 UTC, Uknown wrote:
>>> I don't see the error you are talking about:
>>> https://run.dlang.io/is/XWPIc1
>>>
>>> Are you using the latest compiler?
>>
>> Compile with -unittest.
>>
>> And yes; I'm using DMD 2.079.0.
>
> Now I feel silly. Anyway, I played around with your code. One thing I
> found was `cons.head` returns a `T`, which can't be appended to a
> string. You can fix this with `cons.head.to!string`, where `to` is from
> std.conv. I'm not sure why IFTI isn't deducing `T` to be `int` though.
> Hopefully some one else can help out here.
>
> What I did notice though is that when
> `string list2string(T)(List!T list)` was changed to
> `string list2string(T)(VariantN!(16LU, Nil, Tuple!(T, "head", This*,
> "tail")) list)`
> The compiler correctly deduce `T` to be `int`

I played with it as well by hacking the following:

string list2string(L)(L list)
{
import std.traits : TemplateArgsOf;
alias T = TemplateArgsOf!L[2][0];

// ...
}

I hit the same problem that you describe. (Additionally, list2string 
does not return anything.)


Ali



Re: Function template argument deduction

2018-04-06 Thread Uknown via Digitalmars-d-learn

On Saturday, 7 April 2018 at 05:58:10 UTC, Paul Backus wrote:

On Saturday, 7 April 2018 at 05:46:07 UTC, Uknown wrote:
I don't see the error you are talking about: 
https://run.dlang.io/is/XWPIc1


Are you using the latest compiler?


Compile with -unittest.

And yes; I'm using DMD 2.079.0.


Now I feel silly. Anyway, I played around with your code. One 
thing I found was `cons.head` returns a `T`, which can't be 
appended to a string. You can fix this with 
`cons.head.to!string`, where `to` is from std.conv. I'm not sure 
why IFTI isn't deducing `T` to be `int` though. Hopefully some 
one else can help out here.


What I did notice though is that when
`string list2string(T)(List!T list)` was changed to
`string list2string(T)(VariantN!(16LU, Nil, Tuple!(T, "head", 
This*, "tail")) list)`

The compiler correctly deduce `T` to be `int`


Re: Function template argument deduction

2018-04-06 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 7 April 2018 at 05:46:07 UTC, Uknown wrote:
I don't see the error you are talking about: 
https://run.dlang.io/is/XWPIc1


Are you using the latest compiler?


Compile with -unittest.

And yes; I'm using DMD 2.079.0.


Re: Function template argument deduction

2018-04-06 Thread Uknown via Digitalmars-d-learn

On Saturday, 7 April 2018 at 05:10:05 UTC, Paul Backus wrote:
I'm playing around with functional programming in D, and have 
run into a problem with the following code:


[...]


I don't see the error you are talking about: 
https://run.dlang.io/is/XWPIc1


Are you using the latest compiler?


Function template argument deduction

2018-04-06 Thread Paul Backus via Digitalmars-d-learn
I'm playing around with functional programming in D, and have run 
into a problem with the following code:


--- list.d
import std.variant: Algebraic, This, visit;
import std.typecons: Tuple, tuple;

struct Nil {}
alias List(T) = Algebraic!(
Nil,
Tuple!(T, "head", This*, "tail")
);
alias Cons(T) = Tuple!(T, "head", List!T*, "tail");

List!T* list(T)(T[] items...)
{
if (items.length == 0)
return new List!T(Nil());
else
return new List!T(Cons!T(items[0], list(items[1..$])));
}

string list2string(T)(List!T list)
{
import std.stdio: write;

list.visit!(
(Nil _) => "nil",
(Cons!T cons) => "cons(" ~ cons.head ~ ", " ~ 
list2string(*cons.tail) ~ ")"

);
}


unittest {
List!int* myList = list(1, 2, 3);

assert(list2string(*myList) == "cons(1, cons(2, cons(3, 
nil)))");

}

---

The error I get is "template list.list2string cannot deduce 
function from argument types [...]"; i.e., the compiler can't 
figure out that T is supposed to be 'int'.


My question is, why not? Is there anything I can do to get this 
to work? The compiler seems to be able to handle this sort of 
thing in general (e.g., it can deduce 'int' from an argument of 
type 'Tuple!(int, int)'), so what makes this particular case fail?


Figuring out template argument deduction

2011-05-20 Thread Andrej Mitrovic
After reading the Argument Deduction section in 
http://d-programming-language.org/template.html for the umpteenth time, I still 
don't quite grok how things work.

For example:

template Foo(T1 : T1[], T2) { pragma(msg, T1); }
template Bar(T1 : T2[], T2) { pragma(msg, T1); }

alias Foo!(int[], int) foo;   // T1 = int
alias Bar!(int[], int) bar;   // T1 = int[]

void main() { }

In the docs it says that these cases refer to:
"2. If the type specialization is dependent on a type parameter, the type of 
that parameter is set to be the corresponding part of the type argument."

So what does "corresponding part" mean? It sounds so ambiguous that I can't 
figure it out.


Re: Template argument deduction

2011-03-02 Thread Tom

El 01/03/2011 16:05, Ali Çehreli escribió:

On 02/28/2011 07:39 PM, Tom wrote:

 > foo([[1,2],[3,4],[5,6]]); // ERROR [1]
 > bar([[1,2],[3,4],[5,6]]); // OK
 > foo!int([[1,2],[3,4],[5,6]]); // OK

...

 > void foo(T)(T[2][] t) {
 > writeln(typeid(t));
 > }
 >
 > void bar(T)(T[][] t) {
 > writeln(typeid(t));
 > }

On 03/01/2011 04:30 AM, bearophile wrote:

 > Ali Çehreli:
 >
 >> That's because the type of literals like [1, 2] are slices (dynamic
 >> arrays), not fixed-sized arrays.
 >
 > Then why is this accepted?
 >
 > foo!int([[1,2],[3,4],[5,6]]); // OK

If I have to guess, I think supplying T as int now becomes a problem of
matching [1,2] with int[2] and it already works:

int[2] a = [1, 2];
int[2][] b = [ [1, 2] ];

I don't know whether the compiler should go the extra mile and help Tom
in the original case. :-/

Ali



I should post on D newsgroup. Perhaps Walter or Andrei could enlight us 
about this.


Thanks,
Tom;


Re: Template argument deduction

2011-03-01 Thread Ali Çehreli

On 02/28/2011 07:39 PM, Tom wrote:

> foo([[1,2],[3,4],[5,6]]); // ERROR [1]
> bar([[1,2],[3,4],[5,6]]); // OK
> foo!int([[1,2],[3,4],[5,6]]); // OK

...

> void foo(T)(T[2][] t) {
> writeln(typeid(t));
> }
>
> void bar(T)(T[][] t) {
> writeln(typeid(t));
> }

On 03/01/2011 04:30 AM, bearophile wrote:

> Ali Çehreli:
>
>> That's because the type of literals like [1, 2] are slices (dynamic
>> arrays), not fixed-sized arrays.
>
> Then why is this accepted?
>
> foo!int([[1,2],[3,4],[5,6]]); // OK

If I have to guess, I think supplying T as int now becomes a problem of 
matching [1,2] with int[2] and it already works:


int[2] a = [1, 2];
int[2][] b = [ [1, 2] ];

I don't know whether the compiler should go the extra mile and help Tom 
in the original case. :-/


Ali



Re: Template argument deduction

2011-03-01 Thread bearophile
Ali Çehreli:

> That's because the type of literals like [1, 2] are slices (dynamic 
> arrays), not fixed-sized arrays.

Then why is this accepted?

foo!int([[1,2],[3,4],[5,6]]); // OK

Bye,
bearophile


Re: Template argument deduction

2011-02-28 Thread Ali Çehreli

On 02/28/2011 07:39 PM, Tom wrote:

I have...

import std.stdio;

int main(string[] args) {
foo([[1,2],[3,4],[5,6]]); // ERROR [1]
bar([[1,2],[3,4],[5,6]]); // OK
foo!int([[1,2],[3,4],[5,6]]); // OK

return 0;
}

void foo(T)(T[2][] t) {
writeln(typeid(t));
}

void bar(T)(T[][] t) {
writeln(typeid(t));
}

[1]
src\main.d(4): Error: template main.foo(T) does not match any function
template declaration
src\main.d(4): Error: template main.foo(T) cannot deduce template
function from argument types !()(int[][])


Why can't compiler deduce template parameters from arguments in the
first instantiation?

Thanks in advance,
Tom;


That's because the type of literals like [1, 2] are slices (dynamic 
arrays), not fixed-sized arrays.


import std.stdio;

void main()
{
writeln(typeof([1,2]).stringof);
}

The output of that program is

int[]

Ali



Template argument deduction

2011-02-28 Thread Tom

I have...

import std.stdio;

int main(string[] args) {
foo([[1,2],[3,4],[5,6]]); // ERROR [1]
bar([[1,2],[3,4],[5,6]]); // OK
foo!int([[1,2],[3,4],[5,6]]); // OK

return 0;
}

void foo(T)(T[2][] t) {
writeln(typeid(t));
}

void bar(T)(T[][] t) {
writeln(typeid(t));
}

[1]
src\main.d(4): Error: template main.foo(T) does not match any function 
template declaration
src\main.d(4): Error: template main.foo(T) cannot deduce template 
function from argument types !()(int[][])



Why can't compiler deduce template parameters from arguments in the 
first instantiation?


Thanks in advance,
Tom;


Re: Class template argument deduction from constructor call

2010-10-29 Thread Juanjo Alvarez

On Wed, 27 Oct 2010 21:26:21 +0100, div0  wrote:

this(T t) {
this(string x) {
this(int x) {




autof0 = new Foo("wtf?");
autof1 = new Foo(42);


Best match?


Re: Class template argument deduction from constructor call

2010-10-28 Thread Jérôme M. Berger
Steven Schveighoffer wrote:
> On Wed, 27 Oct 2010 16:26:21 -0400, div0  wrote:
> 
>> class Foo(T) {
>> this(T t) {
>> bar = t;
>> }
>>
>> this(string x) {
>> }
>>
>> this(int x) {
>> }
>>
>> T bar;
>> }
>>
>> autof0 = new Foo("wtf?");
>> autof1 = new Foo(42);
>>
>> What's T in any of the above?
> 
> translates to:
> auto f0 = new Foo!(string)("wtf?");
> auto f0 = new Foo!(int)(42);
> 
> Both of which error, since T can be neither int nor string, or Foo would
> contain conflicting constructors.
> 
> Your question is akin to asking why IFTI doesn't work on something like
> this:
> 
> T foo(T)(int x);
> 
> What Jerome was referring to is something like this:
> 
> class Foo(T)
> {
>   this(T t) {}
>   this(T t, string x);
> }
> 
> which should be unambiguous and completely doable.
> 
> The thing is, when a templated class is to be instantiated without
> giving a complete set of template arguments, then it should use IFTI. 
> The decision to try IFTI is not ambiguous, but depending on how you
> implement the constructors, the overloading can be ambiguous.
> 
Exactly, it should be possible to have consistent behaviour for
template class constructors and template functions: they should both
work and fail in similar circumstances.

Jerome
-- 
mailto:jeber...@free.fr
http://jeberger.free.fr
Jabber: jeber...@jabber.fr



signature.asc
Description: OpenPGP digital signature


Re: Class template argument deduction from constructor call

2010-10-27 Thread Steven Schveighoffer
On Wed, 27 Oct 2010 22:10:24 -0400, Steven Schveighoffer  
 wrote:



To answer the OP's question, I don't think there's anything technical  
restricting the compiler from doing this.  I believe it's been proposed  
several times.  If you want to, you can work around the issue by making  
a wrapper constructor function:


Foo!T makeFoo(T)(T t)
{
   return new Foo!T(t);
}


I should add, it would be ambiguous to do something like this:

class Foo(T, U)
{
   this(T t, U u) {}
   this(U u, T t) {}
}

This kind of situation currently doesn't exist in IFTI, since only  
templates that have exactly one member and it is a function can  
participate in IFTI.


But if the classes are made to work in normal cases, then I think IFTI can  
be extended to support this kind of thing


-Steve


Re: Class template argument deduction from constructor call

2010-10-27 Thread Steven Schveighoffer

On Wed, 27 Oct 2010 16:26:21 -0400, div0  wrote:


On 27/10/2010 21:02, "Jérôme M. Berger" wrote:

div0 wrote:

On 27/10/2010 20:36, sergk wrote:

class Foo(T) {
  this(T t) {
  bar = t;
  }
  T bar;
}

void main() {
  auto a = new Foo(123); // doesn't work
  auto b = new Foo!(int)(123); // work, but redundant
}

Is there any technical limitations preventing this, or its just a
compiler bug?


It's not a bug.

I guess it could be a short cut, but it can only ever work when the
class has exactly one constructor, which seems a bit of a pointless
short cut and adds an unneccassiry corner case to the language spec.


Why would it only be able to work when there is exactly one
constructor? Doesn't function overloading work with templates?

This works here:

void foo(T) (T x) {
}

void foo(T, U) (T x, U y) {
}

void main()
{
 foo (3);
 foo (3, "azerty");
}

Jerome


class Foo(T) {
this(T t) {
bar = t;
}

this(string x) {
}

this(int x) {
}

T bar;
}

autof0 = new Foo("wtf?");
autof1 = new Foo(42);

What's T in any of the above?


translates to:
auto f0 = new Foo!(string)("wtf?");
auto f0 = new Foo!(int)(42);

Both of which error, since T can be neither int nor string, or Foo would  
contain conflicting constructors.


Your question is akin to asking why IFTI doesn't work on something like  
this:


T foo(T)(int x);

What Jerome was referring to is something like this:

class Foo(T)
{
  this(T t) {}
  this(T t, string x);
}

which should be unambiguous and completely doable.

The thing is, when a templated class is to be instantiated without giving  
a complete set of template arguments, then it should use IFTI.  The  
decision to try IFTI is not ambiguous, but depending on how you implement  
the constructors, the overloading can be ambiguous.


To answer the OP's question, I don't think there's anything technical  
restricting the compiler from doing this.  I believe it's been proposed  
several times.  If you want to, you can work around the issue by making a  
wrapper constructor function:


Foo!T makeFoo(T)(T t)
{
  return new Foo!T(t);
}

-Steve


Re: Class template argument deduction from constructor call

2010-10-27 Thread Jonathan M Davis
On Wednesday, October 27, 2010 13:26:21 div0 wrote:
> On 27/10/2010 21:02, "Jérôme M. Berger" wrote:
> > div0 wrote:
> >> On 27/10/2010 20:36, sergk wrote:
> >>> class Foo(T) {
> >>> 
> >>>   this(T t) {
> >>>   
> >>>   bar = t;
> >>>   
> >>>   }
> >>>   T bar;
> >>> 
> >>> }
> >>> 
> >>> void main() {
> >>> 
> >>>   auto a = new Foo(123); // doesn't work
> >>>   auto b = new Foo!(int)(123); // work, but redundant
> >>> 
> >>> }
> >>> 
> >>> Is there any technical limitations preventing this, or its just a
> >>> compiler bug?
> >> 
> >> It's not a bug.
> >> 
> >> I guess it could be a short cut, but it can only ever work when the
> >> class has exactly one constructor, which seems a bit of a pointless
> >> short cut and adds an unneccassiry corner case to the language spec.
> >> 
> > Why would it only be able to work when there is exactly one
> > 
> > constructor? Doesn't function overloading work with templates?
> > 
> > This works here:
> > void foo(T) (T x) {
> > }
> > 
> > void foo(T, U) (T x, U y) {
> > }
> > 
> > void main()
> > {
> > 
> >  foo (3);
> >  foo (3, "azerty");
> > 
> > }
> > 
> > Jerome
> 
> class Foo(T) {
> this(T t) {
> bar = t;
> }
> 
>   this(string x) {
>   }
> 
>   this(int x) {
>   }
> 
> T bar;
> }
> 
> auto  f0 = new Foo("wtf?");
> auto  f1 = new Foo(42);
> 
> What's T in any of the above?
> 
> There's no obvious answer for the first 2 and anything anybody says will
> be a source of endless arguments and bike shedding.

The obvious answer would be that this shouldn't compile because it's ambiguous. 
If you force the constructors which conflict with the templated constructor to 
be 
template specializations, then the problem goes away. However, IIRC, 
unfortunately, at the moment, you can't have a function which has a templated 
and non-templated version regardless of the number of parameters, though I 
believe that there is a bug report on it.

- Jonathan M Davis


Re: Class template argument deduction from constructor call

2010-10-27 Thread div0

On 27/10/2010 21:02, "Jérôme M. Berger" wrote:

div0 wrote:

On 27/10/2010 20:36, sergk wrote:

class Foo(T) {
  this(T t) {
  bar = t;
  }
  T bar;
}

void main() {
  auto a = new Foo(123); // doesn't work
  auto b = new Foo!(int)(123); // work, but redundant
}

Is there any technical limitations preventing this, or its just a
compiler bug?


It's not a bug.

I guess it could be a short cut, but it can only ever work when the
class has exactly one constructor, which seems a bit of a pointless
short cut and adds an unneccassiry corner case to the language spec.


Why would it only be able to work when there is exactly one
constructor? Doesn't function overloading work with templates?

This works here:

void foo(T) (T x) {
}

void foo(T, U) (T x, U y) {
}

void main()
{
 foo (3);
 foo (3, "azerty");
}

Jerome


class Foo(T) {
   this(T t) {
   bar = t;
   }

this(string x) {
}

this(int x) {
}

   T bar;
}

autof0 = new Foo("wtf?");
autof1 = new Foo(42);

What's T in any of the above?

There's no obvious answer for the first 2 and anything anybody says will 
be a source of endless arguments and bike shedding.


--
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk


Re: Class template argument deduction from constructor call

2010-10-27 Thread Jérôme M. Berger
div0 wrote:
> On 27/10/2010 20:36, sergk wrote:
>> class Foo(T) {
>>  this(T t) {
>>  bar = t;
>>  }
>>  T bar;
>> }
>>
>> void main() {
>>  auto a = new Foo(123); // doesn't work
>>  auto b = new Foo!(int)(123); // work, but redundant
>> }
>>
>> Is there any technical limitations preventing this, or its just a
>> compiler bug?
> 
> It's not a bug.
> 
> I guess it could be a short cut, but it can only ever work when the
> class has exactly one constructor, which seems a bit of a pointless
> short cut and adds an unneccassiry corner case to the language spec.
> 
Why would it only be able to work when there is exactly one
constructor? Doesn't function overloading work with templates?

This works here:

void foo(T) (T x) {
}

void foo(T, U) (T x, U y) {
}

void main()
{
foo (3);
foo (3, "azerty");
}

Jerome
-- 
mailto:jeber...@free.fr
http://jeberger.free.fr
Jabber: jeber...@jabber.fr



signature.asc
Description: OpenPGP digital signature


Re: Class template argument deduction from constructor call

2010-10-27 Thread div0

On 27/10/2010 20:36, sergk wrote:

class Foo(T) {
 this(T t) {
 bar = t;
 }
 T bar;
}

void main() {
 auto a = new Foo(123); // doesn't work
 auto b = new Foo!(int)(123); // work, but redundant
}

Is there any technical limitations preventing this, or its just a compiler bug?


It's not a bug.

I guess it could be a short cut, but it can only ever work when the 
class has exactly one constructor, which seems a bit of a pointless 
short cut and adds an unneccassiry corner case to the language spec.


--
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk


Class template argument deduction from constructor call

2010-10-27 Thread sergk
class Foo(T) {
this(T t) {
bar = t;
}
T bar;
}

void main() {
auto a = new Foo(123); // doesn't work
auto b = new Foo!(int)(123); // work, but redundant
}

Is there any technical limitations preventing this, or its just a compiler bug?


-- 
serg.