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









Bill Baxter <dnewsgroup billbaxter.com> 