Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
August 29, 2006 Suggestion: function template overloading | ||||
---|---|---|---|---|
| ||||
It would be very nice if you could overload function templates as you can in C++. Here is what I mean: void f(T)(T val) {...} void f(int val) {...} //error: conflicts with the template function It would allow you to write special cases for types that need it. Here is an example: int CMP__compare(T)(T left, T right) { return(left < right ? -1 : (left > right ? 1 : 0)); } class Array(T) { typedef int function(T, T) compare_func_t; final int findOrdered(T obj) { return(findOrdered(CMP__compare, obj)); } int findOrdered(compare_func_t cmp_func, T obj) { //use 'cmp_func' with binary search to find 'obj' from the array... } final void sort() { sort(CMP__compare); } void sort(compare_func_t cmp_func) {...}; } One could ask why not to compare 'obj' directly in 'findOrdered()', i.e. why to wrap the comparision inside a function template. This way you can easily affect how 'obj' is searched. For example: struct Stru { int a, b; } int CMP__compare(Stru left, Stru right) { if(left.a == -1 || right.a == -1) return(CMP__compare(left.b, right.b)); else return(CMP__compare(left.a, right.a)); } int CMP__compareInv(T)(T left, T right) { return(-CMP__compare(left, right)); } void func() { int pos; Array!(Stru) a; Stru s; ... pos = a.findOrdered(s); ... a.sort(CMP__compareInv); } |
August 29, 2006 Re: Suggestion: function template overloading | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kristian | Kristian wrote:
>
> It would be very nice if you could overload function templates as you can in C++. Here is what I mean:
>
> void f(T)(T val) {...}
>
> void f(int val) {...} //error: conflicts with the template function
>
> It would allow you to write special cases for types that need it.
void f(T)(T val) {}
void f()(int val) {}
Sean
|
August 29, 2006 Re: Suggestion: function template overloading | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | On Tue, 29 Aug 2006 21:04:53 +0300, Sean Kelly <sean@f4.ca> wrote:
> Kristian wrote:
>> It would be very nice if you could overload function templates as you can in C++. Here is what I mean:
>> void f(T)(T val) {...}
>> void f(int val) {...} //error: conflicts with the template function
>> It would allow you to write special cases for types that need it.
>
> void f(T)(T val) {}
> void f()(int val) {}
>
>
> Sean
Ah, thanks! I missed _that_ one completely... :/
But now I can't get the following to work:
bool equal(T)(T l, T r) {
return l == r;
}
bool equal()(Foo l, Foo r) {
return l.m_val == r.m_val;
}
class Foo {
int m_val = 0;
}
class Bar(T) {
this() {
m_val = new T;
}
bool eq(T obj) {
return(equal(m_val, obj)); //error: matches more than one template, equal(T) and equal()
}
T m_val;
}
void main() {
Bar!(Foo) bar = new Bar!(Foo);
Foo foo = new Foo;
printf("%d\n", bar.eq(foo));
}
It seems that 'binding' is done when 'Bar' is compiled, not when 'bar' variable is declared.
|
August 29, 2006 Re: Suggestion: function template overloading | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kristian | Kristian wrote:
> On Tue, 29 Aug 2006 21:04:53 +0300, Sean Kelly <sean@f4.ca> wrote:
>
>> Kristian wrote:
>>> It would be very nice if you could overload function templates as you can in C++. Here is what I mean:
>>> void f(T)(T val) {...}
>>> void f(int val) {...} //error: conflicts with the template function
>>> It would allow you to write special cases for types that need it.
>>
>> void f(T)(T val) {}
>> void f()(int val) {}
>>
>>
>> Sean
>
> Ah, thanks! I missed _that_ one completely... :/
>
> But now I can't get the following to work:
>
> bool equal(T)(T l, T r) {
> return l == r;
> }
> bool equal()(Foo l, Foo r) {
> return l.m_val == r.m_val;
> }
>
> class Foo {
> int m_val = 0;
> }
>
> class Bar(T) {
> this() {
> m_val = new T;
> }
>
> bool eq(T obj) {
> return(equal(m_val, obj)); //error: matches more than one template, equal(T) and equal()
> }
>
> T m_val;
> }
>
> void main() {
> Bar!(Foo) bar = new Bar!(Foo);
> Foo foo = new Foo;
>
> printf("%d\n", bar.eq(foo));
> }
>
> It seems that 'binding' is done when 'Bar' is compiled, not when 'bar' variable is declared.
In this case, it should choose equal()( Foo ... ) over equal(T)( T ...) because the Foo overload is the most specialized for the supplied parameters. Unfortunately, implicit template support in DMD is still pretty thin so you're probably running into a compiler limitation rather than a problem with the spec. Instead of:
equal()( Foo l, Foo r )
try:
equal( T : Foo )( Foo l, Foo r )
and see what happens. I've found that with a bit of experimentation (and perhaps some wrapper code) you can usually get ITI to work as desired, and simply remove the work-around code as DMD improves.
Sean
|
August 29, 2006 Re: Suggestion: function template overloading | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote:
> Kristian wrote:
>>
>> It would be very nice if you could overload function templates as you can in C++. Here is what I mean:
>>
>> void f(T)(T val) {...}
>>
>> void f(int val) {...} //error: conflicts with the template function
>>
>> It would allow you to write special cases for types that need it.
>
> void f(T)(T val) {}
> void f()(int val) {}
Or:
void f(T:int)(T val) {}
The trouble is that D has problems with specialization, but that's a compiler problem.
C++ has complex rules regarding mixing functions and function templates with the same name. D just sidesteps the problem by disallowing that. There's no loss of functionality.
I think the reason C++ did that was because the template design originally didn't allow template specialization, and when it did, it was stuck with the legacy code.
|
August 29, 2006 Re: Suggestion: function template overloading | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | On Tue, 29 Aug 2006 21:44:35 +0300, Sean Kelly <sean@f4.ca> wrote:
> Kristian wrote:
>> On Tue, 29 Aug 2006 21:04:53 +0300, Sean Kelly <sean@f4.ca> wrote:
>>
>>> Kristian wrote:
>>>> It would be very nice if you could overload function templates as you can in C++. Here is what I mean:
>>>> void f(T)(T val) {...}
>>>> void f(int val) {...} //error: conflicts with the template function
>>>> It would allow you to write special cases for types that need it.
>>>
>>> void f(T)(T val) {}
>>> void f()(int val) {}
>>>
>>>
>>> Sean
>> Ah, thanks! I missed _that_ one completely... :/
>> But now I can't get the following to work:
>> bool equal(T)(T l, T r) {
>> return l == r;
>> }
>> bool equal()(Foo l, Foo r) {
>> return l.m_val == r.m_val;
>> }
>> class Foo {
>> int m_val = 0;
>> }
>> class Bar(T) {
>> this() {
>> m_val = new T;
>> }
>> bool eq(T obj) {
>> return(equal(m_val, obj)); //error: matches more than one template, equal(T) and equal()
>> }
>> T m_val;
>> }
>> void main() {
>> Bar!(Foo) bar = new Bar!(Foo);
>> Foo foo = new Foo;
>> printf("%d\n", bar.eq(foo));
>> }
>> It seems that 'binding' is done when 'Bar' is compiled, not when 'bar' variable is declared.
>
> In this case, it should choose equal()( Foo ... ) over equal(T)( T ...) because the Foo overload is the most specialized for the supplied parameters. Unfortunately, implicit template support in DMD is still pretty thin so you're probably running into a compiler limitation rather than a problem with the spec. Instead of:
>
> equal()( Foo l, Foo r )
>
> try:
>
> equal( T : Foo )( Foo l, Foo r )
>
> and see what happens. I've found that with a bit of experimentation (and perhaps some wrapper code) you can usually get ITI to work as desired, and simply remove the work-around code as DMD improves.
>
>
> Sean
Ok, thanks again!
|
Copyright © 1999-2021 by the D Language Foundation