On 8/14/17 9:48 AM, Dominikus Dittes Scherkl wrote:
if I use fixed-type functions, I can do the following:

uint foo(uint n)
{
++n; // modify n - as this function has received a copy of n, this is always possible
    return 42;
}

uint bar(const uint n)
{
    assert(foo(n)==42);
    return 17;
}

void main()
{
    bar(3);
}


But if I try the same with a template parameter, it doesn't work:

import std.traits; // Unqual

uint foo(T)(Unqual!T n) // first try
{
    ++n; // modify should be possible
    return 42;
}

uint foo2(T)(T n) // second try
{
    ++n; // modify fails, as T is const
    return 42;
}

uint bar(T)(const T n)
{
    assert(foo(n)==42u); // cannot deduce arguments - why?!?
assert(foo2(n)==42u); // here it can deduce the arguments, but the function cannot modify n
    return 17;
}

void main()
{
    bar(3);
}

Any ideas what I need to do to make this work?

This isn't exactly supported. Implicit Function Template Instantiation (IFTI) will deduce the parameters to be the types that you pass in. You can't deduce them and then change the parameter types. This is a limitation of IFTI that I have struggled with in the past.

What you can do, is:

auto foo(T)(T n) if (is(T == Unqual!T))
{
   // normal implementation
}

auto foo(T)(T n) if (!is(T == Unqual!T) && isImplicitlyConvertible!(T, Unqual!T))
{
   return foo!(Unqual!T)(n);
}

Hopefully the inliner cuts out the extra call.

-Steve

Reply via email to