digitalmars.D.learn - Q about template function overloads
- Bill Baxter (59/59) Dec 17 2006 Given a templated array-like class that looks like:
- Bill Baxter (8/21) Dec 17 2006 This second part of my question seems to be a result of bug 688[1].
- Bill Baxter (17/43) Dec 17 2006 Gah, sorry to continue this monologue, but apparently my belief that the...
- Lutger (22/52) Dec 18 2006 Hopefully these bugs you mention get fixed. I'm not very big on
Given a templated array-like class that looks like: class Array(T) { ... } How can I write a two overloaded versions of func, one which takes T[] and one which takes Array!(T), and have both return an Array!(T)? In this case the Dummy trick[1] doesn't seem to be of much use. [1] http://d.puremagic.com/issues/show_bug.cgi?id=337 That only seems to work when the Dummy is a specific type, not a parameterized type. Am I stuck with static if's in this case? What I'd like to write: --------- // clean simple obvious, but doesn't compile Array!(T) func(T)(Array!(T) a) { ... } Array!(T) func(T)(T[] a) { ... } --------- What I think I have to write instead ---------- // Not as clear or correct, but compiles template _ArrayTForT(T) { static if( is( T S: S[]) ) { alias ndarray!(S) _ArrayTForT; } else { // really should check here that T==Array!(S) for some S alias T _ArrayTForT; } } _ArrayTForT!(T) diag(T)(T v) { alias _ArrayTForT!(T) ArrayT; static if( is( T S: S[]) ) { writefln("T is a D array"); return new ArrayT; } else { // should be more specific check! writefln("T is (maybe) an Array"); return new ArrayT; } } ------------- Also how do I write the equivalent of this: static if( is( T S: S[]) ) { alias Array!(S) _ArrayTForT; } For the case where T is a user-defined array type: /// doesn't work! static if( is( T S: Array!(S)) ) { alias Array!(S) _ArrayTForT; } It really shouldn't just be an "else" catch-all in the code above. It should be checking for an instantiation of Array!(). --bb
Dec 17 2006
Bill Baxter wrote:Also how do I write the equivalent of this: static if( is( T S: S[]) ) { alias Array!(S) _ArrayTForT; } For the case where T is a user-defined array type: /// doesn't work! static if( is( T S: Array!(S)) ) { alias Array!(S) _ArrayTForT; } It really shouldn't just be an "else" catch-all in the code above. It should be checking for an instantiation of Array!().This second part of my question seems to be a result of bug 688[1]. That is, the check 'is(T S:Array!(S))' *does* work if Array is a struct, just not if it's a class. But I would still be interested in any suggestions for how to do the overloading in a more elegant way. [1] http://d.puremagic.com/issues/show_bug.cgi?id=688 --bb
Dec 17 2006
Gah, sorry to continue this monologue, but apparently my belief that the dummy trick wouldn't work ALSO came from a manifestation of bug 688. This *does* work: FooStruct!(T) func(T)(FooStruct!(T) a) { writefln("Calling FooStruct version"); return a; } FooStruct!(T) func(dumm=void,T)(T[] a) { FooStruct!(T) ret; writefln("Calling [] version"); return ret; } I think I'm going to have to put my blas/lapack array math module on hold for a bit till this bug gets fixed. The errors and workarounds are becoming a little too detrimental to productivity. --bb Bill Baxter wrote:Bill Baxter wrote:Also how do I write the equivalent of this: static if( is( T S: S[]) ) { alias Array!(S) _ArrayTForT; } For the case where T is a user-defined array type: /// doesn't work! static if( is( T S: Array!(S)) ) { alias Array!(S) _ArrayTForT; } It really shouldn't just be an "else" catch-all in the code above. It should be checking for an instantiation of Array!().This second part of my question seems to be a result of bug 688[1]. That is, the check 'is(T S:Array!(S))' *does* work if Array is a struct, just not if it's a class. But I would still be interested in any suggestions for how to do the overloading in a more elegant way. [1] http://d.puremagic.com/issues/show_bug.cgi?id=688 --bb
Dec 17 2006
Bill Baxter wrote:Given a templated array-like class that looks like: class Array(T) { ... } How can I write a two overloaded versions of func, one which takes T[] and one which takes Array!(T), and have both return an Array!(T)? In this case the Dummy trick[1] doesn't seem to be of much use. [1] http://d.puremagic.com/issues/show_bug.cgi?id=337 That only seems to work when the Dummy is a specific type, not a parameterized type. Am I stuck with static if's in this case? What I'd like to write: --------- // clean simple obvious, but doesn't compile Array!(T) func(T)(Array!(T) a) { ... } Array!(T) func(T)(T[] a) { ... } ---------Hopefully these bugs you mention get fixed. I'm not very big on templates, something like this is how I would do a workaround: class Array(T) { alias T* ptr; // tag that matches T[].ptr ... } Array!(T) func(A, T = typeof(*A.ptr) )(A array) { static if ( is(A == Array!(T)) ) { pragma(msg, "Array!(T)"); ... } else { pragma(msg, "T[]"); ... } } Don't know if it is acceptable to you, but it works.
Dec 18 2006