Yeah, type deduction with modifiers is inconsistent. In some cases matching T to const(U) gives U == tailconst(T), but not in others. The problem exists with pointers, arrays, and (if we ever get it) Michel Fortin's const(Object)ref.
A big part of the problem is that it can match with implicit conversions, but the type is never actually converted. eg. is(shared(int*) T : const(U), U) should match and give U == shared(const(int)*) "bearophile" <[email protected]> wrote in message news:[email protected]... >A D2 program: > > > T[] foo(T)(const T[] x) { > //static assert(is(U == int)); // false > static assert(is(T == const(int))); > return new T[1]; > } > U[] bar(U)(const U[] y) { > static assert(is(U == int)); > return foo(y); > } > void main() { > bar([1]); > } > > > DMD 2.054 gives: > test.d(8): Error: cannot implicitly convert expression (foo(y)) of type > const(int)[] to int[] > test.d(11): Error: template instance test.bar!(int) error instantiating > > > Do you know why T of foo is const(int) instead of int? Isn't the "const" > of foo(T)(const T[] x) de-structuring the const nature of x? Is is > possible to change/"fix" this? > > This causes me problems because many of my functions have "in" arguments. > When they call each other they don't compile, as in this example (here I > have used "const" arguments just for clarity). > > > I have had to use code like this: > > Unqual![] foo(T)(const T[] x) { > return new Unqual!T[1]; > } > U[] bar(U)(const U[] y) { > return foo(y); > } > void main() { > bar([1]); > } > > Bye and thank you, > bearophile
