↑ ↓ ← → Ben Hinkle <bhinkle4 juno.com>
writes:
I have a question about overloading and templates. Here's my problem. I have
a function that I want to overload with another function. The trouble is
the function is in a template. For example I have something like
template foo(T) {
void foo(T* x) {...}
}
template foo(T) {
void foo(T[] x) {...}
}
I want users to write code that looks like
foo!(int)(y);
no matter if y is int* or int[]. The two templates as written above don't
work because one can't have two templates with the same name in the same
scope. So right now I'm using static opCalls:
struct foo(T) {
static void opCall(T* x) {...}
static void opCall(T[] x) {...}
}
I could write something like
template foo(T) {
void foo(T* x) {...}
void foo(T[] x) {...}
}
and make users write
foo!(int).foo(y)
but I'd prefer not to do that. If I try writing
foo!(int)(y)
the compiler complains
function expected before (), not 'void'
Basically I'm arguing that the special case of allowing users to write
foo!(int)(...)
when foo has the form
template foo(T) {
void foo(...)
}
should be extended to handle overloaded functions in the template. If there
is a way to do this currently that is less hacky than using static opCalls
please let me know.
-Ben
↑ ↓ ← → Sean Kelly <sean f4.ca>
writes:
Ben Hinkle wrote:
I have a question about overloading and templates. Here's my problem. I have
a function that I want to overload with another function. The trouble is
the function is in a template. For example I have something like
template foo(T) {
void foo(T* x) {...}
}
template foo(T) {
void foo(T[] x) {...}
}
I want users to write code that looks like
foo!(int)(y);
no matter if y is int* or int[]. The two templates as written above don't
work because one can't have two templates with the same name in the same
scope.
But you can have two specialized templates with the same name in the
same scope:
C:\code\d\demo>type overload.d
template foo(T) {
void foo(T x) { printf( "generic\n" ); }
}
template foo(T : T*) {
void foo(T* x) { printf( "pointer\n" ); }
}
template foo(T : T[]) {
void foo(T[] x) { printf( "array\n" ); }
}
void main()
{
int x = 5;
int a[1];
foo!(int)(5);
foo!(int*)(&x);
foo!(int[])(a);
}
C:\code\d\demo>dmd overload.d
C:\bin\dmd\bin\..\..\dm\bin\link.exe overload,,,user32+kernel32/noi;
C:\code\d\demo>overload
generic
pointer
array
↑ ↓ ← → Ben Hinkle <bhinkle4 juno.com>
writes:
Sean Kelly wrote:
Ben Hinkle wrote:
I have a question about overloading and templates. Here's my problem. I
have a function that I want to overload with another function. The
trouble is the function is in a template. For example I have something
like
template foo(T) {
void foo(T* x) {...}
}
template foo(T) {
void foo(T[] x) {...}
}
I want users to write code that looks like
foo!(int)(y);
no matter if y is int* or int[]. The two templates as written above don't
work because one can't have two templates with the same name in the same
scope.
But you can have two specialized templates with the same name in the
same scope:
C:\code\d\demo>type overload.d
template foo(T) {
void foo(T x) { printf( "generic\n" ); }
}
template foo(T : T*) {
void foo(T* x) { printf( "pointer\n" ); }
}
template foo(T : T[]) {
void foo(T[] x) { printf( "array\n" ); }
}
void main()
{
int x = 5;
int a[1];
foo!(int)(5);
foo!(int*)(&x);
foo!(int[])(a);
}
C:\code\d\demo>dmd overload.d
C:\bin\dmd\bin\..\..\dm\bin\link.exe overload,,,user32+kernel32/noi;
C:\code\d\demo>overload
generic
pointer
array
cool - thanks! I hadn't thought of using specialization.
I'll still have a problem when I want to specialize on associative arrays
but I didn't get into that in my original post. I actually want my
templates to take 2 parameters (Key,Value) and specialize for various
containers. My I'll try foo(Key,Value:Value[Key]) or something...
thanks again though
↑ ↓ ← → Andy Friesen <andy ikagames.com>
writes:
Ben Hinkle wrote:
cool - thanks! I hadn't thought of using specialization.
I'll still have a problem when I want to specialize on associative arrays
but I didn't get into that in my original post. I actually want my
templates to take 2 parameters (Key,Value) and specialize for various
containers. My I'll try foo(Key,Value:Value[Key]) or something...
thanks again though
If you figure this one out, I'd love to know. I tried to work this out
awhile ago, but never got anywhere.
It's possible to specialize on an associative array if the key or value
type is not a template argument, or if the key and value types are
identical, but, as far as I can tell, that's the limit of what D's
template specialization mechanism is capable of:
template Foo(T : int[T]) // works
template Foo(T : T[int]) // works
template Foo(T : T[T]) // works
template Foo(T,U : T[U]) // useless: requires Foo!(int, int[char[]])
-- andy
↑ ↓ ← → Sean Kelly <sean f4.ca>
writes:
In article <cieohm$1av6$1 digitaldaemon.com>, Andy Friesen says...
If you figure this one out, I'd love to know. I tried to work this out
awhile ago, but never got anywhere.
It's possible to specialize on an associative array if the key or value
type is not a template argument, or if the key and value types are
identical, but, as far as I can tell, that's the limit of what D's
template specialization mechanism is capable of:
template Foo(T,U : T[U]) // useless: requires Foo!(int, int[char[]])
I'm pretty sure this is a bug. Perhaps it should go in the MIID thread.
Sean