December 12, 2012
On 12/12/2012 07:37 AM, Cube wrote:
> On Wednesday, 12 December 2012 at 15:21:16 UTC, Ali Çehreli wrote:
>> On 12/12/2012 06:49 AM, Cube wrote:
>> > Better example code for my other problem. How can I make the
>> 3rd foo
>> > work on Datas?
>> >
>> > --
>> > struct Data(T)
>> > {
>> > T elem;
>> > }
>>
>> Data is a struct template, not a type (until instantiated).
>>
>> > void foo(T)(T t) if(is(T == Data)) // ?
>>
>> This works:
>>
>> void foo(T)(T t) if(is(T == Data!T))
>
> It doesn't seem to work for me, it uses the first foo. And I can't see
> how it would work, actually.
> If T is a Data!float, then wouldn't
> is(T == Data!T)
> be equal to
> is(Data!float == Data!Data!float)
> ?

I have to deal with the magical 'is expression' again! :p

First, also notice that you ar not passing Data!T but a pointer to Data!T. This program works:

import std.stdio;
import std.traits;

struct Data(T)
{
    T elem;
}

void main()
{
    foo(1);
    foo([1,1]);

    auto tmp1 = new Data!(int);
    tmp1.elem = 3;
    foo(tmp1);

    auto tmp2 = new Data!(string);
    tmp2.elem = "hello";
    foo(tmp2);
}

void foo(T)(T t) if(!isArray!T && !is(T ThisIsNeededButUnusable : Data!U*, U))
{
    writeln(t + 1);
}

void foo(T)(T t) if(isArray!T)
{
    for(int i = 0; i < t.length; i++)
        writeln(t[i]);
}

void foo(T)(T t) if (is(T ThisIsNeededButUnusable : Data!U*, U))
{
    writeln("desired");

    // Note that both of the 'if's are replaced with 'static if's.
    // Also, both are 'pointers' in the conditionals.
    static if(is(T == Data!int*))
        writeln(t.elem + 1);
    else static if(is(T == Data!string*))
        writeln(t.elem);
}

I think ThisIsNeededButUnusable above is a compiler bug. It has a use when the body of the 'is' is used inside template parameter lists but not in a template constraint. It is still needed to satisfy the syntax... (?)

Ali

December 12, 2012
ixid:

> It seems very similar to a function overload to me. Why is picking T[] in preference to T different to picking uint over ulong for an overloaded function used on a uint?

The name T can refer to any type, including a U[], while built-in types like uint are atomic, they can't refer to a composed type.
And there is difference between a built-in type where both the programmer and the compiler know about, and generic user defined types. And template types are used in an exact way, unlike function overloading they don't perform implicit type conversions.

Bye,
bearophile
1 2
Next ›   Last »