Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 18, 2007 Template member functions conflicting | ||||
---|---|---|---|---|
| ||||
class Bang(T) { void fn(U)( Bang!(U) ot) {} void fn(int q) {} } Why do the two member functions conflict here? One takes a class instance and a type, the other takes an int. If this is intended, and it's not possible to overload a function with a template function, then maybe it should be? |
February 18, 2007 Re: Template member functions conflicting | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robin Allen | "Robin Allen" <r.a3@ntlworld.com> wrote in message news:er9bin$1ksb$1@digitalmars.com... > class Bang(T) > { > void fn(U)( Bang!(U) ot) {} > > void fn(int q) {} > } > > Why do the two member functions conflict here? One takes a class instance and a type, the other takes an int. > > If this is intended, and it's not possible to overload a function with a template function, then maybe it should be? The page http://www.digitalmars.com/d/template-comparison.html says that it's unfortunately not possible. What's worse, you can use specialized template functions as that page suggests, but then you surrender IFTI, so you will no longer be able to write "b.fn(4)" and have it automatically determine that you want the int version. You'll have to write "b.fn!(int)(4)". The reason this isn't possible (I've heard) is that function overloading and template specialization are two completely separate concepts, and getting them to work together is very hard indeed. |
February 19, 2007 Re: Template member functions conflicting | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robin Allen | Robin Allen wrote: > class Bang(T) > { > void fn(U)( Bang!(U) ot) {} > void fn(int q) {} > } > > Why do the two member functions conflict here? One takes a class instance and a type, the other takes an int. > > If this is intended, and it's not possible to overload a function with a template function, then maybe it should be? They conflict, but there is an effective workaround, just turn the function into a nullary template (template with zero parameters): import stdext.stdio; class Bang(T) { void fn(U)(Bang!(U) ot) { writeln("U template:", typeid(U) ); } void fn() (int q) { writeln("nullary template");} } void main(char[][] args) { auto foo = new Bang!(char); foo.fn(new Bang!(char)); foo.fn(42); } -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D |
February 19, 2007 Re: Template member functions conflicting | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | Bruno Medeiros napisał(a):
> Robin Allen wrote:
>> class Bang(T)
>> {
>> void fn(U)( Bang!(U) ot) {}
>> void fn(int q) {}
>> }
>>
>> Why do the two member functions conflict here? One takes a class instance and a type, the other takes an int.
>>
>> If this is intended, and it's not possible to overload a function with a template function, then maybe it should be?
>
> They conflict, but there is an effective workaround, just turn the
> function into a nullary template (template with zero parameters):
>
> import stdext.stdio;
>
> class Bang(T)
> {
> void fn(U)(Bang!(U) ot) { writeln("U template:", typeid(U) ); }
> void fn() (int q) { writeln("nullary template");}
> }
>
>
> void main(char[][] args) {
> auto foo = new Bang!(char);
>
> foo.fn(new Bang!(char));
> foo.fn(42);
> }
>
Just a thought.
Couldn't be normal functions just discarded in favor of templated versions (without need to write 2 pairs of parenthesis of course - I mean internally in compiler)? It would probably be much more consistent with templated versions...
Best Regards
Marcin Kuszczak
|
February 19, 2007 Re: Template member functions conflicting | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aarti_pl | Aarti_pl wrote: > Bruno Medeiros napisał(a): >> Robin Allen wrote: >>> class Bang(T) >>> { >>> void fn(U)( Bang!(U) ot) {} >>> void fn(int q) {} >>> } >>> >>> Why do the two member functions conflict here? One takes a class instance and a type, the other takes an int. >>> >>> If this is intended, and it's not possible to overload a function with a template function, then maybe it should be? >> >> They conflict, but there is an effective workaround, just turn the >> function into a nullary template (template with zero parameters): >> >> import stdext.stdio; >> >> class Bang(T) >> { >> void fn(U)(Bang!(U) ot) { writeln("U template:", typeid(U) ); } >> void fn() (int q) { writeln("nullary template");} >> } >> >> >> void main(char[][] args) { >> auto foo = new Bang!(char); >> >> foo.fn(new Bang!(char)); >> foo.fn(42); >> } >> > > Just a thought. > > Couldn't be normal functions just discarded in favor of templated versions (without need to write 2 pairs of parenthesis of course - I mean internally in compiler)? It would probably be much more consistent with templated versions... > > > Best Regards > Marcin Kuszczak Except that regular member functions and member function templates are not equivalent: Member function templates are implicitly "final," and are not entered into the vtable. -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org |
February 19, 2007 Re: Template member functions conflicting | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kirk McDonald | Kirk McDonald napisał(a):
> Except that regular member functions and member function templates are not equivalent: Member function templates are implicitly "final," and are not entered into the vtable.
>
I was expecting that there are different for some reasons :-)
I am just thinking about improving it a little bit as I had to deal with overloading of template methods with normal functions and it is annoying....
Still, isn't it possible to make template functions like normal functions, so that they will not be 'final' by default?
It would be probably also bonus for template functions itself...
BR
Marcin Kuszczak
|
February 19, 2007 Re: Template member functions conflicting | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | "Bruno Medeiros" <brunodomedeiros+spam@com.gmail> wrote in message news:erc3nr$2lis$1@digitalmars.com... > > They conflict, but there is an effective workaround, just turn the function into a nullary template (template with zero parameters): > > import stdext.stdio; > > class Bang(T) > { > void fn(U)(Bang!(U) ot) { writeln("U template:", typeid(U) ); } > void fn() (int q) { writeln("nullary template");} > } > > > void main(char[][] args) { > auto foo = new Bang!(char); > > foo.fn(new Bang!(char)); > foo.fn(42); > } Huh! Pretty sweet. :) |
February 19, 2007 Re: Template member functions conflicting | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | Bruno Medeiros wrote:
> Robin Allen wrote:
>> class Bang(T)
>> {
>> void fn(U)( Bang!(U) ot) {}
>> void fn(int q) {}
>> }
>>
>> Why do the two member functions conflict here? One takes a class instance and a type, the other takes an int.
>>
>> If this is intended, and it's not possible to overload a function with a template function, then maybe it should be?
>
> They conflict, but there is an effective workaround, just turn the
> function into a nullary template (template with zero parameters):
>
> import stdext.stdio;
>
> class Bang(T)
> {
> void fn(U)(Bang!(U) ot) { writeln("U template:", typeid(U) ); }
> void fn() (int q) { writeln("nullary template");}
> }
>
>
> void main(char[][] args) {
> auto foo = new Bang!(char);
>
> foo.fn(new Bang!(char));
> foo.fn(42);
> }
>
I tried this, but for me it just crashes the compiler. Probably because it's actually opMul I'm defining rather than a normal function. (I'm trying to make a Matrix class that you can multiply by another matrix or a vector.)
The actual code is more like this:
class Matrix(int X,int Y,T)
{
Matrix!(X,OY,T) opMul(OY)( Matrix!(Y,OY,T) ot );
Vector!(Y,T) opMul( Vector!(X,T) vec );
}
The only way I've been able to do it is by replacing one of the operator functions with a regular function. But it would be nice to do it with the * sign.
|
February 19, 2007 Re: Template member functions conflicting | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robin Allen | Robin Allen wrote:
> Bruno Medeiros wrote:
>> Robin Allen wrote:
>>> class Bang(T)
>>> {
>>> void fn(U)( Bang!(U) ot) {}
>>> void fn(int q) {}
>>> }
>>>
>>> Why do the two member functions conflict here? One takes a class instance and a type, the other takes an int.
>>>
>>> If this is intended, and it's not possible to overload a function with a template function, then maybe it should be?
>>
>> They conflict, but there is an effective workaround, just turn the
>> function into a nullary template (template with zero parameters):
>>
>> import stdext.stdio;
>>
>> class Bang(T)
>> {
>> void fn(U)(Bang!(U) ot) { writeln("U template:", typeid(U) ); }
>> void fn() (int q) { writeln("nullary template");}
>> }
>>
>>
>> void main(char[][] args) {
>> auto foo = new Bang!(char);
>>
>> foo.fn(new Bang!(char));
>> foo.fn(42);
>> }
>>
>
> I tried this, but for me it just crashes the compiler. Probably because it's actually opMul I'm defining rather than a normal function. (I'm trying to make a Matrix class that you can multiply by another matrix or a vector.)
>
> The actual code is more like this:
>
> class Matrix(int X,int Y,T)
> {
> Matrix!(X,OY,T) opMul(OY)( Matrix!(Y,OY,T) ot );
> Vector!(Y,T) opMul( Vector!(X,T) vec );
> }
>
> The only way I've been able to do it is by replacing one of the operator functions with a regular function. But it would be nice to do it with the * sign.
>
>
That won't typically work as you cannot overload on return types. If user code /only ever/ passed either Matrix or Vector with your opMul it might pass... but I'm dubious. In this case I would recommend just defining opMul for Matrix, and providing a function for multiplying with a Vector.
The fact that it crashes the compiler, though, is another manner. Try to find a small test case that produces it and you may have a bug report to file.
-- Chris Nicholson-Sauls
|
February 19, 2007 Re: Template member functions conflicting | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | Chris Nicholson-Sauls wrote: > Robin Allen wrote: >> Bruno Medeiros wrote: >>> Robin Allen wrote: >>>> class Bang(T) >>>> { >>>> void fn(U)( Bang!(U) ot) {} >>>> void fn(int q) {} >>>> } >>>> >>>> Why do the two member functions conflict here? One takes a class instance and a type, the other takes an int. >>>> >>>> If this is intended, and it's not possible to overload a function with a template function, then maybe it should be? >>> >>> They conflict, but there is an effective workaround, just turn the >>> function into a nullary template (template with zero parameters): >>> >>> import stdext.stdio; >>> >>> class Bang(T) >>> { >>> void fn(U)(Bang!(U) ot) { writeln("U template:", typeid(U) ); } >>> void fn() (int q) { writeln("nullary template");} >>> } >>> >>> >>> void main(char[][] args) { >>> auto foo = new Bang!(char); >>> >>> foo.fn(new Bang!(char)); >>> foo.fn(42); >>> } >>> >> >> I tried this, but for me it just crashes the compiler. Probably because it's actually opMul I'm defining rather than a normal function. (I'm trying to make a Matrix class that you can multiply by another matrix or a vector.) >> >> The actual code is more like this: >> >> class Matrix(int X,int Y,T) >> { >> Matrix!(X,OY,T) opMul(OY)( Matrix!(Y,OY,T) ot ); >> Vector!(Y,T) opMul( Vector!(X,T) vec ); >> } >> >> The only way I've been able to do it is by replacing one of the operator functions with a regular function. But it would be nice to do it with the * sign. >> >> > > That won't typically work as you cannot overload on return types. No the rule is that you can't overload _only_ on return type. If the arguments are distinct then you can overload. This works for instance: struct Foo { int frob(int a) { return a; } char[] frob(char[] a) { return a; } } void main() { Foo f; int x = f.frob(3); char[] y = f.frob("hithere"); } > If user code /only ever/ passed either Matrix or Vector with your opMul it might pass... but I'm dubious. In this case I would recommend just defining opMul for Matrix, and providing a function for multiplying with a Vector. > The fact that it crashes the compiler, though, is another manner. Try to find a small test case that produces it and you may have a bug report to file. Yeh, that sounds like a bug. File it here when you have a small repro case: http://d.puremagic.com/issues/ --bb |
Copyright © 1999-2021 by the D Language Foundation