On Sun, 30 Oct 2011 10:36:26 -0400, Andrei Alexandrescu <seewebsiteforem...@erdani.org> wrote:

On 10/30/11 5:16 AM, J Arrizza wrote:
        You should use either std.traits.isXxx systematically, or
        patterns systematically, but not both at the same time.
        Personally I prefer isXxx because they foster simple logic to
        decide what overloads should apply.


    Also, when posting, you may want to include complete short programs
    so others can try them quickly.


Andrei, I thought I had posted the entire program. Here it is again
using only traits as you recommend:

    import std.stdio;
    import std.traits;
    void abc(T) (T parm1)
       if (isNarrowString!T || (!isStaticArray!T && !isDynamicArray!T))
       {
       writeln("simpleparm: ", parm1);
       }
    void abc(T) (T parm1)
       if (!isNarrowString!T && (isDynamicArray!T || isStaticArray!T) )
       {
       writeln("array : ", parm1);
       }
    void main(string[] args)
       {
         writeln("v4");
         abc(1);
         abc("str");
         int[] arr = [1, 2];
         abc(arr);
         int[2] arr2 = [3, 4];
         abc(arr2);
       }

Thanks, sorry for having missed that.

The code as above is canonical. I think restricted templates are the way to go for most code. Pattern matching on types is rather arcane and should be let to a few advanced uses (such as implementing traits themselves).

The attraction of using specializations instead of constraints (aside from the readability) is that specializations do not require modifying the non-specialized templates.

For example:

void abc(T)(T parm1) {...}
void abc(T:int)(T parm1) {...}

vs:

void abc(T)(T parm1) if (!is(T : int)) {...}
void abc(T)(T parm1) if (is(T: int)) {...}

Note that the if(!is(T :int)) is required in the base case. This can quickly get out of hand if you have lots of specializations (see any phobos modules for lots of examples). It might be nice if constrained templates took precedence over non-constrained ones.

-Steve

Reply via email to