default values depending on type of template variable

Simen Kjærås simen.kjaras at gmail.com
Wed Sep 11 09:01:43 UTC 2019


On Wednesday, 11 September 2019 at 08:35:02 UTC, berni wrote:
> I'd like to write a template, that takes a different default 
> value depending on the type of a variable. I tried this, but it 
> doesn't work:
>
>>void main()
>>{
>>    double a = 1e-8;
>>    double b = 1e-10;
>>    float c = 1e-4;
>>    float d = 1e-6;
>>
>>    assert(!test(a));
>>    assert(test(b));
>>    assert(!test(c));
>>    assert(test(d));
>>}
>> 
>>auto test(T, U)(T value, U limit=1e-9)
>>{
>>    return value<limit;
>>}
>>
>>auto test(T:float)(T value)
>>{
>>    return test(value, 1e-5);
>>}
>
> Although being called with a double in the first two tests, the 
> second overload is always used and therefore the first test 
> fails. And without this overload, the last test obviously 
> doesn't pass.
>
> Is there a way, to provide default values for template 
> parameters depending on the type of an other parameter?

unittest
{
     double a = 1e-8;
     double b = 1e-10;
     float c = 1e-4;
     float d = 1e-6;

     assert(!test(a));
     assert(test(b));
     assert(!test(c));
     assert(test(d));
}


auto test(T, U)(T value, U limit = limit!T) {
     return value < limit;
}

// Solution 1:
template limit(T) {
     static if (is(T == float)) {
         enum limit = 1e-5;
     } else {
         enum limit = 1e-9;
     }
}

// Solution 2:
enum limit(T : float)  = 1e-5;
enum limit(T : double) = 1e-9;

With some tricks this can also be inlined:

enum If(bool b, T...) = T[b ? 0 : 1];
auto test(T, U)(T value, U limit = If!(is(T == float), 1e-5, 
1e-9)) {
     return value < limit;
}

--
   Simen


More information about the Digitalmars-d-learn mailing list