www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Resolving conflicting functions

reply Derek Parnell <derek nomail.afraid.org> writes:
I have a Currency data type,based on a struct.

I want to divide a Currency value by a scalar to return a Currency and I
want to divide a Currency value by another Currency value to return a
scalar. This below is my attempt but fails to compile. How does one do
this?


    // ------------------------    
    real opDiv(Currency pFactor)
    // ------------------------    
    {
       return mData / pFactor.mData;
    }
    
    // ------------------------    
    Currency opDiv(T)(T pFactor)
    // ------------------------    
    {
       Currency temp;
        
       temp = this.mData / pFactor;
       
       return temp;
    }
    
I get the message ...

    template Currency.opDiv(T) conflicts with function Currency.opDiv


-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
4/12/2007 11:44:07 AM
Dec 03 2007
parent reply BCS <ao pathlink.com> writes:
Reply to Derek,

 I have a Currency data type,based on a struct.
 
 I want to divide a Currency value by a scalar to return a Currency and
 I want to divide a Currency value by another Currency value to return
 a scalar. This below is my attempt but fails to compile. How does one
 do this?
 
 // ------------------------
 real opDiv(Currency pFactor)
 // ------------------------
 {
 return mData / pFactor.mData;
 }
 // ------------------------
 Currency opDiv(T)(T pFactor)
 // ------------------------
 {
 Currency temp;
 temp = this.mData / pFactor;
 
 return temp;
 }
 I get the message ...
 
 template Currency.opDiv(T) conflicts with function Currency.opDiv
 
you can't have a template and non-template by the same name here is the nasty solution, ther might be a better one, but this should work. // ------------------------ Ret!(T) opDiv(T)(T pFactor) // ------------------------ { Ret!(T) temp; static if(is(T == Currency)) temp = mData / pFactor.mData; else temp = this.mData / pFactor; return temp; }
Dec 03 2007
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
BCS wrote:
 Reply to Derek,
 
 I have a Currency data type,based on a struct.

 I want to divide a Currency value by a scalar to return a Currency and
 I want to divide a Currency value by another Currency value to return
 a scalar. This below is my attempt but fails to compile. How does one
 do this?

 // ------------------------
 real opDiv(Currency pFactor)
 // ------------------------
 {
 return mData / pFactor.mData;
 }
 // ------------------------
 Currency opDiv(T)(T pFactor)
 // ------------------------
 {
 Currency temp;
 temp = this.mData / pFactor;

 return temp;
 }
 I get the message ...

 template Currency.opDiv(T) conflicts with function Currency.opDiv
you can't have a template and non-template by the same name here is the nasty solution, ther might be a better one, but this should work. // ------------------------ Ret!(T) opDiv(T)(T pFactor) // ------------------------ { Ret!(T) temp; static if(is(T == Currency)) temp = mData / pFactor.mData; else temp = this.mData / pFactor; return temp; }
Turning the plain opDiv into a template with a different number of arguments might work too: // ------------------------ real opDiv(T=void,S=void)(Currency pFactor) // ------------------------ { return mData / pFactor.mData; } // ------------------------ Currency opDiv(T)(T pFactor) // ------------------------ { Currency temp; temp = this.mData / pFactor; return temp; } I say might because I'm not really sure when that trick works and when it doesn't. I posted a question about it a while back but it seems no one else knows exactly how it works either. (Or, more likely, they just found the question too boring. ;-) --bb
Dec 03 2007
next sibling parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Tue, 04 Dec 2007 10:04:15 +0900, Bill Baxter wrote:

 
 // ------------------------
 real opDiv(T=void,S=void)(Currency pFactor)
 // ------------------------
 {
    return mData / pFactor.mData;
 }
 I say might because I'm not really sure when that trick works and when 
 it doesn't.
Sorry, but it didn't work. -- Derek (skype: derek.j.parnell) Melbourne, Australia 4/12/2007 12:50:05 PM
Dec 03 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Derek Parnell wrote:
 On Tue, 04 Dec 2007 10:04:15 +0900, Bill Baxter wrote:
 
  
 // ------------------------
 real opDiv(T=void,S=void)(Currency pFactor)
 // ------------------------
 {
    return mData / pFactor.mData;
 }
 I say might because I'm not really sure when that trick works and when 
 it doesn't.
Sorry, but it didn't work.
Sigh. These little games we have to play to get D templates to play nicely with others are quite annoying. --bb
Dec 03 2007
prev sibling parent Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Bill Baxter wrote:
 BCS wrote:
 
 Reply to Derek,

 I have a Currency data type,based on a struct.

 I want to divide a Currency value by a scalar to return a Currency and
 I want to divide a Currency value by another Currency value to return
 a scalar. This below is my attempt but fails to compile. How does one
 do this?

 // ------------------------
 real opDiv(Currency pFactor)
 // ------------------------
 {
 return mData / pFactor.mData;
 }
 // ------------------------
 Currency opDiv(T)(T pFactor)
 // ------------------------
 {
 Currency temp;
 temp = this.mData / pFactor;

 return temp;
 }
 I get the message ...

 template Currency.opDiv(T) conflicts with function Currency.opDiv
you can't have a template and non-template by the same name here is the nasty solution, ther might be a better one, but this should work. // ------------------------ Ret!(T) opDiv(T)(T pFactor) // ------------------------ { Ret!(T) temp; static if(is(T == Currency)) temp = mData / pFactor.mData; else temp = this.mData / pFactor; return temp; }
Turning the plain opDiv into a template with a different number of arguments might work too: // ------------------------ real opDiv(T=void,S=void)(Currency pFactor) // ------------------------ { return mData / pFactor.mData; } // ------------------------ Currency opDiv(T)(T pFactor) // ------------------------ { Currency temp; temp = this.mData / pFactor; return temp; } I say might because I'm not really sure when that trick works and when it doesn't. I posted a question about it a while back but it seems no one else knows exactly how it works either. (Or, more likely, they just found the question too boring. ;-) --bb
What about a template with /no/ arguments? real opDiv()(Currentcy pFactor) { return mData / pFactor.mData; } -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org
Dec 03 2007
prev sibling next sibling parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Tue, 4 Dec 2007 00:57:59 +0000 (UTC), BCS wrote:
 you can't have a template and non-template by the same name
Yeah, I guess so. But why?
 here is the nasty solution, ther might be a better one, but this should work.
 
 // ------------------------
 Ret!(T) opDiv(T)(T pFactor)
 // ------------------------
 {
   Ret!(T) temp;
Ummm ... what is 'Ret!' and where can it be found? -- Derek (skype: derek.j.parnell) Melbourne, Australia 4/12/2007 12:45:12 PM
Dec 03 2007
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Derek Parnell wrote:
 On Tue, 4 Dec 2007 00:57:59 +0000 (UTC), BCS wrote:
 you can't have a template and non-template by the same name
Yeah, I guess so. But why?
 here is the nasty solution, ther might be a better one, but this should work.

 // ------------------------
 Ret!(T) opDiv(T)(T pFactor)
 // ------------------------
 {
   Ret!(T) temp;
Ummm ... what is 'Ret!' and where can it be found?
You'll have to make it. A little static if template like template Ret(T) { static if (is(T==Currency)) { alias real Ret; } else { alias Currency Ret; } } Makes programming with templates lots of fun, huh? :-) --bb
Dec 03 2007
parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Tue, 04 Dec 2007 11:18:56 +0900, Bill Baxter wrote:

 You'll have to make it. A little static if template like
 
 template Ret(T) {
     static if (is(T==Currency)) { alias real Ret; }
     else { alias Currency Ret; }
 }
I almost go it right. Yes this works. There has got to be a better way! -- Derek (skype: derek.j.parnell) Melbourne, Australia 4/12/2007 2:04:43 PM
Dec 03 2007
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Derek Parnell wrote:
 On Tue, 04 Dec 2007 11:18:56 +0900, Bill Baxter wrote:
 
 You'll have to make it. A little static if template like

 template Ret(T) {
     static if (is(T==Currency)) { alias real Ret; }
     else { alias Currency Ret; }
 }
I almost go it right. Yes this works. There has got to be a better way!
You think that's bad; try doing it for a matrix library where the return type depends on the input types which contain a mix of scalars, vectors, matrices and transforms (special matrices which have an implicit final row.) Hopefully the promised overloading upgrades will help with this. -- Daniel
Dec 03 2007
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Daniel Keep wrote:
 
 Derek Parnell wrote:
 On Tue, 04 Dec 2007 11:18:56 +0900, Bill Baxter wrote:

 You'll have to make it. A little static if template like

 template Ret(T) {
     static if (is(T==Currency)) { alias real Ret; }
     else { alias Currency Ret; }
 }
I almost go it right. Yes this works. There has got to be a better way!
You think that's bad; try doing it for a matrix library where the return type depends on the input types which contain a mix of scalars, vectors, matrices and transforms (special matrices which have an implicit final row.) Hopefully the promised overloading upgrades will help with this. -- Daniel
Here's my take: http://www.dsource.org/projects/openmeshd/browser/trunk/OpenMeshD/OpenMesh/Core/Geometry/MatrixT.d Look for "MultReturnType". :-) I could try to make it more generic but just getting it to work with a specific vector type and matrix type was annoying enough for me. --bb
Dec 03 2007
prev sibling parent reply BCS <ao pathlink.com> writes:
Reply to Daniel,

 Derek Parnell wrote:
 
 On Tue, 04 Dec 2007 11:18:56 +0900, Bill Baxter wrote:
 
 You'll have to make it. A little static if template like
 
 template Ret(T) {
 static if (is(T==Currency)) { alias real Ret; }
 else { alias Currency Ret; }
 }
I almost go it right. Yes this works. There has got to be a better way!
You think that's bad; try doing it for a matrix library where the return type depends on the input types which contain a mix of scalars, vectors, matrices and transforms (special matrices which have an implicit final row.) Hopefully the promised overloading upgrades will help with this. -- Daniel
this would be a nice place to have auto: auto Fn(A, B, C)(A a, B b, C c) { /// lots-o-logic return ret; // return type defined here. }
Dec 04 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
BCS wrote:
 Reply to Daniel,
 
 Derek Parnell wrote:

 On Tue, 04 Dec 2007 11:18:56 +0900, Bill Baxter wrote:

 You'll have to make it. A little static if template like

 template Ret(T) {
 static if (is(T==Currency)) { alias real Ret; }
 else { alias Currency Ret; }
 }
I almost go it right. Yes this works. There has got to be a better way!
You think that's bad; try doing it for a matrix library where the return type depends on the input types which contain a mix of scalars, vectors, matrices and transforms (special matrices which have an implicit final row.) Hopefully the promised overloading upgrades will help with this. -- Daniel
this would be a nice place to have auto: auto Fn(A, B, C)(A a, B b, C c) { /// lots-o-logic return ret; // return type defined here. }
Yeh, that does look more in line with D than sticking a typeof(return) out front. --bb
Dec 04 2007
prev sibling parent BCS <ao pathlink.com> writes:
Reply to Derek,

 On Tue, 4 Dec 2007 00:57:59 +0000 (UTC), BCS wrote:
 
 you can't have a template and non-template by the same name
 
Yeah, I guess so. But why?
 here is the nasty solution, ther might be a better one, but this
 should work.
 
 // ------------------------
 Ret!(T) opDiv(T)(T pFactor)
 // ------------------------
 {
 Ret!(T) temp;
Ummm ... what is 'Ret!' and where can it be found?
sorry, I forgot that part, but Bill got it spot on.
Dec 04 2007
prev sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
BCS wrote:
 Reply to Derek,
 
 I have a Currency data type,based on a struct.

 I want to divide a Currency value by a scalar to return a Currency and
 I want to divide a Currency value by another Currency value to return
 a scalar. This below is my attempt but fails to compile. How does one
 do this?

 // ------------------------
 real opDiv(Currency pFactor)
 // ------------------------
 {
 return mData / pFactor.mData;
 }
 // ------------------------
 Currency opDiv(T)(T pFactor)
 // ------------------------
 {
 Currency temp;
 temp = this.mData / pFactor;

 return temp;
 }
 I get the message ...

 template Currency.opDiv(T) conflicts with function Currency.opDiv
you can't have a template and non-template by the same name here is the nasty solution, ther might be a better one, but this should work. // ------------------------ Ret!(T) opDiv(T)(T pFactor) // ------------------------ { Ret!(T) temp; static if(is(T == Currency)) temp = mData / pFactor.mData; else temp = this.mData / pFactor; return temp; }
I think in D2 you should be able to use typeof(return) to remove the need for the extra helper template, Ret. Totally untried though. // ------------------------ typeof(return) opDiv(T)(T pFactor) // ------------------------ { static if(is(T == Currency)) return mData / pFactor.mData; else return this.mData / pFactor; } --bb
Dec 03 2007
parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Tue, 04 Dec 2007 11:23:18 +0900, Bill Baxter wrote:

 I think in D2 you should be able to use typeof(return) to remove the 
 need for the extra helper template, Ret.
 Totally untried though.
 
 // ------------------------
 typeof(return) opDiv(T)(T pFactor)
 // ------------------------
 {
   static if(is(T == Currency))
     return  mData / pFactor.mData;
   else
     return  this.mData / pFactor;
 }
 
 --bb
Nope. "typeof(return) must be inside a function" -- Derek (skype: derek.j.parnell) Melbourne, Australia 4/12/2007 2:03:49 PM
Dec 03 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Derek Parnell wrote:
 On Tue, 04 Dec 2007 11:23:18 +0900, Bill Baxter wrote:
 
 I think in D2 you should be able to use typeof(return) to remove the 
 need for the extra helper template, Ret.
 Totally untried though.

 // ------------------------
 typeof(return) opDiv(T)(T pFactor)
 // ------------------------
 {
   static if(is(T == Currency))
     return  mData / pFactor.mData;
   else
     return  this.mData / pFactor;
 }

 --bb
Nope. "typeof(return) must be inside a function"
Dang. I had high hopes for that new feature to clean things up. --bb
Dec 03 2007