On Thursday, 4 July 2013 at 18:07:00 UTC, Maxim Fomin wrote:
On Thursday, 4 July 2013 at 15:59:21 UTC, TommiT wrote:
On Thursday, 4 July 2013 at 15:03:54 UTC, Maxim Fomin wrote:
[..]
2) In case of one parameter, a variable isn't tied to any type and usual implicit conversions are applied.

Do you mean that if D had the C++ style implicit conversion operator (using let's say the keyword '@implicit'), then the following would compile?

struct Wrap(T)
{
   T t;
}

struct Toy
{
   alias Wrapped = Wrap!Toy;

   @implicit Wrapped opCast(T : Wrapped)()
   {
       return Wrapped.init;
   }
}

void foo(T)(Wrap!T) { }

void main()
{
   foo(Toy.init);
}


Your implicit syntax is redundant. What C++ does is irrelevant. D has alias this.

My implicit cast operator syntax is not redundant because it's not the same thing as your alias this example. My example would not and should not ever compile.

The difference between alias this relationship and a mere implicit conversion operator is that alias this creates an is-a relationship, whereas implicit conversion operator does not.


On Thursday, 4 July 2013 at 18:07:00 UTC, Maxim Fomin wrote:
import std.stdio;

struct Wrap(T)
{
    T t;
}

struct Toy
{
    alias get this;

    Wrap!Toy get()
    {
        return Wrap!Toy.init;
    }
}

void foo(T)(Wrap!T t)
{
   writeln(T.stringof);
}

void main()
{
    foo(Toy.init);
}

Note, that T is Toy, so there were no type conversion during template instantiation. There was argument conversion after instantiation, as it happens usually. Back to foo function accepting slice - dmd does the same thing.

DMD doesn't do the same thing for static arrays. Due to alias this, your Toy is a Wrap!Toy for all intents and purposes. There's no is-a relationship between a static array type and the dynamic array type which it implicitly converts to. What happens when static array implicitly converts to dynamic array is the same type of implicit conversion which happens when long converts to double. There's no is-a relationship between long and double.


On Thursday, 4 July 2013 at 15:03:54 UTC, Maxim Fomin wrote:
On Thursday, 4 July 2013 at 13:55:17 UTC, TommiT wrote:
On Thursday, 4 July 2013 at 13:45:07 UTC, Maxim Fomin wrote:
Actually if you pass integer static array, dmd deduces T to be int, [..]

And that right there, "dmd deduces T to be int", is the crux of the matter. How on earth is DMD able to deduce T to be int, without using the implicit conversion from int[10] to int[] ?

DMD is stupid, but not that. If it has T[] parameter, and int[10] static array which is convertible to int[] is passed, T is deduced to be int. What other types T can be? A float, object, or pointer to union?

So you admit that DMD does implicit conversion during type deduction?

See above. What type implicit converision did dmd in case of int[10] and int[]. Conversion from int to int?

Here's what the compiler does during type deduction when it sees the following function template and its instantiation:

void foo(T)(T[] da) { }

int[10] sa;
foo(sa);

Step 1:
The compiler tries to figure out the type T such as the parameter da would have the same type as the argument sa which was passed to the function. The complier comes to the conclusion that there is not type which would make the type of da the same as the type of sa. For example, if T were int, then the type of da would be int[] which is not the same as the type of sa which is int[10].

Step 2:
The compiler tries to see if the type of sa could be implicitly converted to something. The compiler realises that sa could be converted to an instance of type int[]. Then the compiler checks if this implicitly converted type could be passed to foo. The compiler figures out that if T is int, then the implicitly converted type int[] matches exactly with the type of the parameter da. Thus, the compiler declares that T must be int.

Step 3:
If the compiler hasn't managed to figure out what T is, it gives an error. If it has found out what T is, the compiler declares that the type deduction has been successfully accomplished.

To answer your question "What implicit conversion did dmd do in the case of int[10] and int[]", see Step 2. At Step 2 the compiler does, or rather checks that it's possible to do, the implicit conversion from int[10] to int[]. That Step 2 right there is what no-one coming from C++ would expect to happen, and according to that quote from TDPL, that Step 2 should not happen in D.

Reply via email to