From slices to perfect imitators: opByValue
Timon Gehr via Digitalmars-d
digitalmars-d at puremagic.com
Thu May 8 02:57:42 PDT 2014
On 05/08/2014 05:58 AM, Andrei Alexandrescu wrote:
> ...
> >
> import std.stdio;
>
> void fun(T)(T x)
> {
> writeln(typeof(x).stringof);
> }
>
> void main()
> {
> immutable(int[]) a = [ 1, 2 ];
> writeln(typeof(a).stringof);
> fun(a);
> }
>
> This program outputs:
>
> immutable(int[])
> immutable(int)[]
>
> which means that the type of that value has subtly and silently changed in the process of passing it to a function.
> ...
This way of stating it is imprecise: What happened is that during
implicit function template instantiation, T was determined to be
immutable(int)[] instead of immutable(int[]). Then 'a' was implicitly
converted from immutable(int[]) to immutable(int)[] just as it would be
done for any function call with those argument and parameter types.
> This change was introduced a while ago (by Kenji I recall) and it enabled a lot of code that was gratuitously rejected.
> This magic of T[] is something that custom ranges can't avail themselves
> of. In order to bring about parity, we'd need to introduce opByValue
> which (if present) would be automatically called whenever the object is
> passed by value into a function.
> ...
There are two independent pieces of magic here, and this proposal
removes none of them in a satisfactory way:
struct S(T){
HeadUnqual!(typeof(this)) opByValue(){ ... }
...
}
void fun(in S!int a){}
void main(){
const S!int s;
fun(s); // error, cannot implicitly convert expression s.opByValue
// of type S!(const(int)) to const(S!int).
}
A better ad-hoc way of resolving this is opImplicitCast and a special
opIFTIdeduce member or something like that.
struct S(T){
alias opIFTIdeduce = HeadUnqual!(typeof(this));
S opImplicitCast(S)(typeof(this) arg){ ... }
...
}
But this just means that now every author of a datatype of suitable kind
has to manually re-implement implicit conversion rules of T[].
A probably even better way is to just allow to specify by annotation
that some templated datatype should mimic T[]'s implicit conversion
rules (and without necessarily providing a direct and overpowered hook
into the IFTI resolution process, though both could be done.)
> This change would allow library designers to provide good solutions to
> making immutable and const ranges work properly - the way T[] works.
> ...
Questionable.
const(T)[] b = ...;
const(T[]) a = b; // =)
Range!(const(T)) s = ...;
const(Range!T) r = s; // =(
More information about the Digitalmars-d
mailing list