Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
February 02, 2016 Variadic template parameters T... bounding | ||||
---|---|---|---|---|
| ||||
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 |
February 02, 2016 Re: Variadic template parameters T... bounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Voitech | 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
}
|
February 02, 2016 Re: Variadic template parameters T... bounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Voitech | 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.
|
February 02, 2016 Re: Variadic template parameters T... bounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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 |
February 02, 2016 Re: Variadic template parameters T... bounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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
|
February 02, 2016 Re: Variadic template parameters T... bounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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.
|
February 02, 2016 Re: Variadic template parameters T... bounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Kozak | 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.
|
February 02, 2016 Re: Variadic template parameters T... bounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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.
|
February 02, 2016 Re: Variadic template parameters T... bounding | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Kozak | 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[]
|
Copyright © 1999-2021 by the D Language Foundation