digitalmars.D - Suggestion: function template overloading
- Kristian (50/50) Aug 29 2006 It would be very nice if you could overload function templates as you ca...
- Sean Kelly (4/13) Aug 29 2006 void f(T)(T val) {}
- Kristian (30/39) Aug 29 2006 Ah, thanks! I missed _that_ one completely... :/
- Sean Kelly (13/65) Aug 29 2006 In this case, it should choose equal()( Foo ... ) over equal(T)( T ...)
- Kristian (8/63) Aug 29 2006 on
- Walter Bright (11/24) Aug 29 2006 Or:
It would be very nice if you could overload function templates as you ca= n = 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 arra= y... } 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 =3D=3D -1 || right.a =3D=3D -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 =3D a.findOrdered(s); ... a.sort(CMP__compareInv); }
Aug 29 2006
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
Aug 29 2006
On Tue, 29 Aug 2006 21:04:53 +0300, Sean Kelly <sean f4.ca> wrote:Kristian wrote:u =It would be very nice if you could overload function templates as yo=can in C++. Here is what I mean: void f(T)(T val) {...} void f(int val) {...} //error: conflicts with the template function=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 =3D=3D r; } bool equal()(Foo l, Foo r) { return l.m_val =3D=3D r.m_val; } class Foo { int m_val =3D 0; } class Bar(T) { this() { m_val =3D 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 =3D new Bar!(Foo); Foo foo =3D new Foo; printf("%d\n", bar.eq(foo)); } It seems that 'binding' is done when 'Bar' is compiled, not when 'bar' = variable is declared.It would allow you to write special cases for types that need it.void f(T)(T val) {} void f()(int val) {} Sean
Aug 29 2006
Kristian wrote:On Tue, 29 Aug 2006 21:04:53 +0300, Sean Kelly <sean f4.ca> wrote: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. SeanKristian wrote: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.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
Aug 29 2006
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 =onyou can in C++. Here is what I mean: void f(T)(T val) {...} void f(int val) {...} //error: conflicts with the template functi=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 =3D=3D r; } bool equal()(Foo l, Foo r) { return l.m_val =3D=3D r.m_val; } class Foo { int m_val =3D 0; } class Bar(T) { this() { m_val =3D new T; } bool eq(T obj) { return(equal(m_val, obj)); //error: matches more than one =It would allow you to write special cases for types that need it.void f(T)(T val) {} void f()(int val) {} Seanr' =template, equal(T) and equal() } T m_val; } void main() { Bar!(Foo) bar =3D new Bar!(Foo); Foo foo =3D new Foo; printf("%d\n", bar.eq(foo)); } It seems that 'binding' is done when 'Bar' is compiled, not when 'ba=) =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 rath=er =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. SeanOk, thanks again!
Aug 29 2006
Sean Kelly wrote:Kristian wrote: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.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) {}
Aug 29 2006