www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Variadic template parameters T... bounding

reply Voitech <woipoi gmail.com> writes:
Hi, Is it possible to bound T... in template with some type ? For 
single Parameter declaration it can be done by T:SomeType but 
variadics does not seems to have that possibility ?
Cheers
Feb 02 2016
next sibling parent Daniel Kozak <kozzi11 gmail.com> writes:
On Tuesday, 2 February 2016 at 13:20:33 UTC, Voitech wrote:
 Hi, Is it possible to bound T... in template with some type ? 
 For single Parameter declaration it can be done by T:SomeType 
 but variadics does not seems to have that possibility ?
 Cheers
import std.stdio; import std.meta: allSatisfy; import std.traits; void some(T...)(T Args) if (allSatisfy!(isIntegral,T)) { writeln(Args); } void main() { some(1); some(1,2,3); some(1,2,3.0); // error }
Feb 02 2016
prev sibling parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Tuesday, 2 February 2016 at 13:20:33 UTC, Voitech wrote:
 Hi, Is it possible to bound T... in template with some type ? 
 For single Parameter declaration it can be done by T:SomeType 
 but variadics does not seems to have that possibility ?
 Cheers
Two possible solutions... If you don't need to know the number of arguments at compile time, you can use normal variadic arguments: void test(T)(T[] args...) { import std.stdio; writeln(T.stringof); } class A { } class B : A { } class C : A { } void main() { test(1,2,3); // int test(4,5,6.9); // double static assert(!__traits(compiles, test(1,"xyz",9))); // unfortunately, this doesn't work either: //test(new B(), new C()); } The last call should work IMO, but it doesn't. I believe that's a compiler bug. The other solution is to use `CommonType` as a template constraint: import std.traits; void test(T...)(T args) if(!is(CommonType!T == void)) { import std.stdio; writeln(T.stringof); } class A { } class B : A { } class C : A { } void main() { test(1,2,3); // (int, int, int) test(4,5,6.9); // (int, int, double) static assert(!__traits(compiles, test(1,"xyz",9))); test(new B(), new C()); // (B, C) } As you can see, here the types don't need to match exactly, but they need to have a common base type.
Feb 02 2016
next sibling parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz wrote:
 The last call should work IMO, but it doesn't. I believe that's 
 a compiler bug.
Filed: https://issues.dlang.org/show_bug.cgi?id=15640
Feb 02 2016
parent reply Daniel Kozak <kozzi11 gmail.com> writes:
On Tuesday, 2 February 2016 at 13:57:54 UTC, Marc Schütz wrote:
 On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz wrote:
 The last call should work IMO, but it doesn't. I believe 
 that's a compiler bug.
Filed: https://issues.dlang.org/show_bug.cgi?id=15640
I would say it is not a bug test!A(new B(), new C()); // works which is what I expected
Feb 02 2016
parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Tuesday, 2 February 2016 at 14:12:54 UTC, Daniel Kozak wrote:
 On Tuesday, 2 February 2016 at 13:57:54 UTC, Marc Schütz wrote:
 On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz wrote:
 The last call should work IMO, but it doesn't. I believe 
 that's a compiler bug.
Filed: https://issues.dlang.org/show_bug.cgi?id=15640
I would say it is not a bug test!A(new B(), new C()); // works which is what I expected
The bug is that `T` is not automatically inferred to be `A`. That's not a restriction of type inference in general: if you mix ints and floats, the common type is deduced correctly, just not for classes.
Feb 02 2016
parent reply Daniel Kozak <kozzi11 gmail.com> writes:
On Tuesday, 2 February 2016 at 14:47:43 UTC, Marc Schütz wrote:
 On Tuesday, 2 February 2016 at 14:12:54 UTC, Daniel Kozak wrote:
 On Tuesday, 2 February 2016 at 13:57:54 UTC, Marc Schütz wrote:
 On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz 
 wrote:
 The last call should work IMO, but it doesn't. I believe 
 that's a compiler bug.
Filed: https://issues.dlang.org/show_bug.cgi?id=15640
I would say it is not a bug test!A(new B(), new C()); // works which is what I expected
if you mix ints and floats, the common type is deduced correctly:
this is a bug for me :). I do not like this. I am ok with (u)byte to int conversion and similar, but mixing float and integral types does not seems to be OK.
Feb 02 2016
parent Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Tuesday, 2 February 2016 at 14:55:42 UTC, Daniel Kozak wrote:
 On Tuesday, 2 February 2016 at 14:47:43 UTC, Marc Schütz wrote:
 if you mix ints and floats, the common type is deduced 
 correctly:
this is a bug for me :). I do not like this. I am ok with (u)byte to int conversion and similar, but mixing float and integral types does not seems to be OK.
I see. But it's also consistent with array type deduction elsewhere: auto a = [1, 2.5]; pragma(msg, typeof(a)); // double[] ... and more importantly: class A { } class B : A { } class C : A { } auto a = [new A(), new B()]; pragma(msg, typeof(a)); // A[]
Feb 02 2016
prev sibling parent Voitech <woipoi gmail.com> writes:
On Tuesday, 2 February 2016 at 13:52:55 UTC, Marc Schütz wrote:
 On Tuesday, 2 February 2016 at 13:20:33 UTC, Voitech wrote:
 [...]
Two possible solutions... If you don't need to know the number of arguments at compile time, you can use normal variadic arguments: [...]
Thank you I'll try that.
Feb 02 2016