www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - how to do template constraints with variadic templates ?

reply Flaze07 <christianseiji.cs gmail.com> writes:
I want to force the variadic templates's type to be of certain 
types, I thought doing this would work
auto sum( A... )( A a ) if( isIntegral!( typeid( a[ 0 ] ) ) )
{
     int temp;
     foreach( t ; a )
     {
         temp += t;
     }
     return temp;
}
but it gives out error
( note : I want all the parameter to be integral, i.e sum( 1, 2, 
5, "error" ); //error
Jul 07 2018
parent reply Flaze07 <christianseiji.cs gmail.com> writes:
On Sunday, 8 July 2018 at 00:46:13 UTC, Flaze07 wrote:
 I want to force the variadic templates's type to be of certain 
 types, I thought doing this would work
 auto sum( A... )( A a ) if( isIntegral!( typeid( a[ 0 ] ) ) )
 {
     int temp;
     foreach( t ; a )
     {
         temp += t;
     }
     return temp;
 }
 but it gives out error
 ( note : I want all the parameter to be integral, i.e sum( 1, 
 2, 5, "error" ); //error
I uhh managed to do it with this code auto sum( A... )( A a ) { static foreach( t ; a ) { static assert( isIntegral!( typeof( t ) ) ); } int temp; foreach( t ; a ) { temp += t; } return temp; } but, I just want to ask something, is the static assert still runned during runtime ?
Jul 07 2018
parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Sunday, 8 July 2018 at 00:52:41 UTC, Flaze07 wrote:
 On Sunday, 8 July 2018 at 00:46:13 UTC, Flaze07 wrote:
 I want to force the variadic templates's type to be of certain 
 types, I thought doing this would work
 auto sum( A... )( A a ) if( isIntegral!( typeid( a[ 0 ] ) ) )
 {
     int temp;
     foreach( t ; a )
     {
         temp += t;
     }
     return temp;
 }
 but it gives out error
 ( note : I want all the parameter to be integral, i.e sum( 1, 
 2, 5, "error" ); //error
I uhh managed to do it with this code auto sum( A... )( A a ) { static foreach( t ; a ) { static assert( isIntegral!( typeof( t ) ) ); } int temp; foreach( t ; a ) { temp += t; } return temp; } but, I just want to ask something, is the static assert still runned during runtime ?
static assert is a compile-time thing - it creates no code in the resulting binary. If it triggers, the code will simply fail to compile, and no code will be generated. If it passes, there's simply no trace of it. Now, you might want to use std.meta.allSatisfy: import std.meta : allSatisfy; auto sum(A...)(A a) if (allSatisfy!(isIntegral, A)) Also, you should probably use CommonType!A for the type of temp, since an int can't hold all the possible values of a long or ulong (or even uint), and you'll thus get unexpected results with large numbers. -- Simen
Jul 07 2018
parent Flaze07 <christianseiji.cs gmail.com> writes:
On Sunday, 8 July 2018 at 02:10:12 UTC, Simen Kjærås wrote:
 Also, you should probably use CommonType!A for the type of 
 temp, since an int can't hold all the possible values of a long 
 or ulong (or even uint), and you'll thus get unexpected results 
 with large numbers.

 --
   Simen
I see, thanks, it's helpful. I really should check out std.meta alot more
Jul 07 2018