www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - default values depending on type of template variable

reply berni <someone something.org> writes:
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?
Sep 11 2019
next sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
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
Sep 11 2019
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 09/11/2019 01:35 AM, berni wrote:
 I'd like to write a template, that takes a different default value 
 depending on the type of a variable.
Like this? import std.stdio; 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)); } template DefaultFor(T) { static if (is (T == float)) { enum DefaultFor = 1e-5; } else static if (is (T == double)) { enum DefaultFor = 1e-9; } else { import std.string; static assert (false, format!"%s not supported"(T.stringof)); } } auto test(T, U)(T value, U limit=DefaultFor!T) { writefln!"%s: %s(%s)"(T.stringof, U.stringof, limit); return value<limit; } Ali
Sep 11 2019
parent berni <someone something.org> writes:
On Wednesday, 11 September 2019 at 09:05:47 UTC, Ali Çehreli 
wrote:
 Like this?
Yet an other template! That's great! :-)
Sep 11 2019