The way that makes the most sense to me is:
void f(T)(Unqual!T t) {}
Given an immutable(T) for instance that I want to call with, it
would
instantiate the template with the signature void f(T), and then
attempt to
call it with the immutable(T). If immutable(T) is not
convertible to the
argument T, then it would produce a compile error as if
attempting to call
any such function that just receives T.
The point here is that I want more control over the signature
of the
instantiated template (reduce the number of permutations
generated for
various calls). Template blow-out is perhaps the biggest and
most well
known day-to-day problem in C++, and tools like this may be
very valuable
to mitigate the disaster.
It seems that your code works if you put the Template Type
explicit:
----
import std.stdio;
import std.traits : Unqual;
void foo(T)(Unqual!T a) {
writeln(typeof(a).stringof, " <-> ", T.stringof);
}
void main() {
int a;
const int b;
immutable int c;
//foo(c); /// Error
foo!(typeof(a))(a);
foo!(typeof(b))(b);
foo!(typeof(c))(c);
}
----