Thread overview | ||||||
---|---|---|---|---|---|---|
|
December 18, 2006 Q about template function overloads | ||||
---|---|---|---|---|
| ||||
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 |
December 18, 2006 Re: Q about template function overloads | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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 |
December 18, 2006 Re: Q about template function overloads | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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
|
December 18, 2006 Re: Q about template function overloads | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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.
|
Copyright © 1999-2021 by the D Language Foundation