www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why can't I have overloading and generics?

reply Caligo <iteronvexor gmail.com> writes:
    struct B { }
    struct C { }
    struct D { }

    struct A {

      ref A foo(B item) {
        /* do something special. */
        return this;
      }

      ref A foo(T)(T item) if(is(T == C) || is(T == D)) {
        /* nothing special, do the same for C and D. */
        return this;
      }
    }

Is this unreasonable?  iirc, C++ supports this, but not D.  What's the
reason? Bug?

What's a good solution to this?

1. a generic `foo()` that uses `static if`s?

2. overload `foo()`, even if it means having function bodies that are
exactly same (code duplication).?

3. mixin templates?  I don't know about this because TDPL says it's
experimental, and I've tried and I get weird errors.
Mar 09 2012
next sibling parent reply sclytrack <sclytrack hotmail.com> writes:
On 03/10/2012 04:32 AM, Caligo wrote:
      struct B { }
      struct C { }
      struct D { }

      struct A {

        ref A foo(B item) {
          /* do something special. */
          return this;
        }

        ref A foo(T)(T item) if(is(T == C) || is(T == D)) {
          /* nothing special, do the same for C and D. */
          return this;
        }
      }

 Is this unreasonable?  iirc, C++ supports this, but not D.  What's the
 reason? Bug?

 What's a good solution to this?

 1. a generic `foo()` that uses `static if`s?

 2. overload `foo()`, even if it means having function bodies that are
 exactly same (code duplication).?

 3. mixin templates?  I don't know about this because TDPL says it's
 experimental, and I've tried and I get weird errors.

I don't know what the best solution is. But the following works. import std.stdio; struct B { } struct C { } struct D { } struct A { ref A foo(T)(T item) if (is(T==B)) { /* do something special. */ writeln("B"); return this; } ref A foo(T)(T item) if(is(T == C) || is(T == D)) { /* nothing special, do the same for C and D. */ writeln("C or D"); return this; } } int main() { A a; B b; C c; a.foo(b); a.foo(c); writeln("Test"); return 0; } -----------------------output B C or D Test
Mar 10 2012
parent David <d dav1d.de> writes:
You can strip

 ref A foo(T)(T item) if (is(T==B)) {

down to: ref A foo(T : B)(T item) // or to match your example ref A foo(T == B)(T item)
Mar 10 2012
prev sibling next sibling parent "so" <so so.so> writes:
On Saturday, 10 March 2012 at 03:32:44 UTC, Caligo wrote:
     struct B { }
     struct C { }
     struct D { }

     struct A {

       ref A foo(B item) {
         /* do something special. */
         return this;
       }

       ref A foo(T)(T item) if(is(T == C) || is(T == D)) {
         /* nothing special, do the same for C and D. */
         return this;
       }
     }

 Is this unreasonable?  iirc, C++ supports this, but not D.  
 What's the
 reason? Bug?

 What's a good solution to this?

 1. a generic `foo()` that uses `static if`s?

 2. overload `foo()`, even if it means having function bodies 
 that are
 exactly same (code duplication).?

 3. mixin templates?  I don't know about this because TDPL says 
 it's
 experimental, and I've tried and I get weird errors.

When it comes to templates if it works in C++ and not in D, you can be sure it is a bug OR future! For this one i am sure it is a bug. Rule is, when language resolves the function it first looks for exact matches then template overloads and i can't see anything wrong in your code. I am not sure but it is probably about "is". Its usage looks pretty in your code, it should not! :)
Mar 10 2012
prev sibling parent "Jesse Phillips" <jessekphillips+D gmail.com> writes:
Templates not overriding non-template functions is a bug

http://d.puremagic.com/issues/show_bug.cgi?id=1528
Mar 10 2012