How to overload operator* for this template?

A

Atlas

Hi,
I implemented a template as:
template <int L, int M, int T>
class Quantity
{
.....
public:
friend Quantity operator*(const Quantity& q1,const Quantity& q2);
.....
};

when I tried to use it as:
////////////////
typedef Quantity<1,0,-2> Acceleration;
typedef Quantity<1,0,0> Length;
const Acceleration GRAV(9.81);
const Length penLen(1);
....=penLen * GRAV;
////////////////////
The compiler complained "no operator defined for Acceleration".
If the both oprands have the same L,M,T, it works. But how to deal with
it if they are different?
And the return value is another issue, because it will have another set
of L,M,T.
I tried the following:
template <int L1, int M1, int T1, int L2, int M2, int T2>
friend Quantity<L1+L2,M1+M2,T1+T2> operator*
(const Quantity<L1,M1,T1>& q1,const Quantity<L2,M2,T2>& q2)
{
Quantity<L1+L2,M1+M2,T1+T2> q;
..........
return q;
},

but failed with " error C2995: 'Quantity<L1*L2,M1*M2,T1*T2> operator
*(const Quantity<L1,M1,T1> &,const Quantity<L2,M2,T2> &)' : template
function has already been defined".


Thanks a lot.
 
M

mlimber

Atlas said:
Hi,
I implemented a template as:
template <int L, int M, int T>
class Quantity
{
....
public:
friend Quantity operator*(const Quantity& q1,const Quantity& q2);
....
};

when I tried to use it as:
////////////////
typedef Quantity<1,0,-2> Acceleration;
typedef Quantity<1,0,0> Length;
const Acceleration GRAV(9.81);
const Length penLen(1);
...=penLen * GRAV;
////////////////////
The compiler complained "no operator defined for Acceleration".
If the both oprands have the same L,M,T, it works. But how to deal with
it if they are different?
And the return value is another issue, because it will have another set
of L,M,T.
I tried the following:
template <int L1, int M1, int T1, int L2, int M2, int T2>
friend Quantity<L1+L2,M1+M2,T1+T2> operator*
(const Quantity<L1,M1,T1>& q1,const Quantity<L2,M2,T2>& q2)
{
Quantity<L1+L2,M1+M2,T1+T2> q;
.........
return q;
},

but failed with " error C2995: 'Quantity<L1*L2,M1*M2,T1*T2> operator
*(const Quantity<L1,M1,T1> &,const Quantity<L2,M2,T2> &)' : template
function has already been defined".


Thanks a lot.

It's probably something to do with the order of your declarations. Post
a minimal but complete example that demonstrates the problem.

Cheers! --M
 
M

mlimber

Atlas said:
Hi,
I implemented a template as:
template <int L, int M, int T>
class Quantity
{
....
public:
friend Quantity operator*(const Quantity& q1,const Quantity& q2);
....
};

when I tried to use it as:
////////////////
typedef Quantity<1,0,-2> Acceleration;
typedef Quantity<1,0,0> Length;
const Acceleration GRAV(9.81);
const Length penLen(1);
...=penLen * GRAV;
////////////////////
The compiler complained "no operator defined for Acceleration".
If the both oprands have the same L,M,T, it works. But how to deal with
it if they are different?
And the return value is another issue, because it will have another set
of L,M,T.
I tried the following:
template <int L1, int M1, int T1, int L2, int M2, int T2>
friend Quantity<L1+L2,M1+M2,T1+T2> operator*
(const Quantity<L1,M1,T1>& q1,const Quantity<L2,M2,T2>& q2)
{
Quantity<L1+L2,M1+M2,T1+T2> q;
.........
return q;
},

but failed with " error C2995: 'Quantity<L1*L2,M1*M2,T1*T2> operator
*(const Quantity<L1,M1,T1> &,const Quantity<L2,M2,T2> &)' : template
function has already been defined".


Thanks a lot.

It may have something to do with the order of your declarations. Post a
minimal but complete piece of code that demonstrates the problem.

Cheers! --M
 
V

Victor Bazarov

Atlas said:
I implemented a template as:
template <int L, int M, int T>
class Quantity
{
....
public:
friend Quantity operator*(const Quantity& q1,const Quantity& q2);

You probably want to drop this declaration from here. Does it really
need to be a friend? If so, you might want to make _all_ 'operator*'
templates friends of all the classes 'Quantity<>':

template<int L1, int M1, int T1, ...> // just like you did below
friend Quantity said:
....
};

when I tried to use it as:
////////////////
typedef Quantity<1,0,-2> Acceleration;
typedef Quantity<1,0,0> Length;
const Acceleration GRAV(9.81);
const Length penLen(1);
...=penLen * GRAV;
////////////////////
The compiler complained "no operator defined for Acceleration".
If the both oprands have the same L,M,T, it works. But how to deal with
it if they are different?
And the return value is another issue, because it will have another set
of L,M,T.
Sure.

I tried the following:
template <int L1, int M1, int T1, int L2, int M2, int T2>
friend Quantity<L1+L2,M1+M2,T1+T2> operator*
(const Quantity<L1,M1,T1>& q1,const Quantity<L2,M2,T2>& q2)
{
Quantity<L1+L2,M1+M2,T1+T2> q;
.........
return q;
},

but failed with " error C2995: 'Quantity<L1*L2,M1*M2,T1*T2> operator
*(const Quantity<L1,M1,T1> &,const Quantity<L2,M2,T2> &)' : template
function has already been defined".

Wrong compiler, maybe?
--------------------------------------- This:
template <int L, int M, int T>
class Quantity
{
public:
Quantity(double = 0);
template<int L1, int M1, int T1, int L2, int M2, int T2>
friend Quantity<L1+L2,M1+M2,T1+T2> operator*
(const Quantity<L1,M1,T1>& q1,const Quantity<L2,M2,T2>& q2);
};

template<int L1, int M1, int T1, int L2, int M2, int T2>
Quantity<L1+L2,M1+M2,T1+T2> operator*
(const Quantity<L1,M1,T1>& q1, const Quantity<L2,M2,T2>& q2)
{
Quantity<L1+L2,M1+M2,T1+T2> q;
return q;
}

typedef Quantity<1,0,-2> Acceleration;
typedef Quantity<1,0,0> Length;

const Acceleration GRAV(9.81);
const Length penLen(1);

int main()
{
Quantity<2,0,-2> q = penLen * GRAV;
}
------------------------------------------- compiles fine with Comeau.

VC++ v8 chokes on it, but it's not something unexpected, really. MS'
compiler has been having troubles with templates and today isn't the
last day of it. I'll ask in microsoft.public.vc.language. Maybe they
already know of a bug reported on this...

V
 
A

Atlas

Thanks so much for so many work. But I still can solve it. I tried your
codes in MSVC2003 but failed with "internal compiler error".

P.S. operator* has to be friend, to conform the internal type
convention.
 
M

mlimber

Atlas said:
Thanks so much for so many work. But I still can solve it. I tried your
codes in MSVC2003 but failed with "internal compiler error".

P.S. operator* has to be friend, to conform the internal type
convention.

First, don't top post (i.e. putting your reply above the post you're
replying to). It's considered impolite.

Please post enough code to demonstrate your problem.

Cheers! --M
 
A

Atlas

OH?I simply use the facility of google groups. If anything wrong,
that's google's convention.
On the other hand, I think my codes are enough for this problem. Other
codes may confuse you. Victor's codes are google example to expain my
question.
Thank you anyway.
 
M

mlimber

Atlas said:
OH?I simply use the facility of google groups. If anything wrong,
that's google's convention.

Incorrect. All you need to do is click on "show options", which you did
above in responding to Victor, and move the cursor *below* the post
you're quoting, which you did not do when responding to Victor. I'm
presently using google, too, and I am perfectly able to follow proper
netiquette with it.
On the other hand, I think my codes are enough for this problem. Other
codes may confuse you.

If you think the posted code is sufficient, that's your call, but don't
be surprised if you get no further responses. See this FAQ for tips on
posting code to this newsgroup:

http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8
Victor's codes are google example to expain my question.

Huh?

Cheers! --M
 
M

mlimber

Atlas said:
This time, the quoted text simply disappeared!

That's because you clicked "Reply" below the message instead of
clicking "show options" and then "Reply".

Cheers! --M
 
V

Victor Bazarov

mlimber said:

Well, if you take a look at my previous post, I gave a complete program
that is, in fact, well-formed but fails to compile with, say, VC++. That
is what the OP is talking about, I suppose. I based it on the OP's code
fragment.

BTW, I submitted the same code in a bug report to MS.

V
 
M

mlimber

Victor said:
Well, if you take a look at my previous post, I gave a complete program
that is, in fact, well-formed but fails to compile with, say, VC++. That
is what the OP is talking about, I suppose. I based it on the OP's code
fragment.

BTW, I submitted the same code in a bug report to MS.

V

And you did fine work, if you don't mind me saying. (My confusion was
more grammatical and semantic than contextual, however.)

Cheers! --M
 
A

Atlas

mlimber said:
And you did fine work, if you don't mind me saying. (My confusion was
more grammatical and semantic than contextual, however.)

Cheers! --M
Victor is correct. That's what I want to solve.
And mlimber, I think you should submit a bug report to google groups.
Finally, thanks everybody.
 
A

Atlas

Victor said:
You probably want to drop this declaration from here. Does it really
need to be a friend? If so, you might want to make _all_ 'operator*'
templates friends of all the classes 'Quantity<>':

template<int L1, int M1, int T1, ...> // just like you did below


Wrong compiler, maybe?
--------------------------------------- This:
template <int L, int M, int T>
class Quantity
{
public:
Quantity(double = 0);
template<int L1, int M1, int T1, int L2, int M2, int T2>
friend Quantity<L1+L2,M1+M2,T1+T2> operator*
(const Quantity<L1,M1,T1>& q1,const Quantity<L2,M2,T2>& q2);
};

template<int L1, int M1, int T1, int L2, int M2, int T2>
Quantity<L1+L2,M1+M2,T1+T2> operator*
(const Quantity<L1,M1,T1>& q1, const Quantity<L2,M2,T2>& q2)
{
Quantity<L1+L2,M1+M2,T1+T2> q;
return q;
}

typedef Quantity<1,0,-2> Acceleration;
typedef Quantity<1,0,0> Length;

const Acceleration GRAV(9.81);
const Length penLen(1);

int main()
{
Quantity<2,0,-2> q = penLen * GRAV;
}
------------------------------------------- compiles fine with Comeau.

VC++ v8 chokes on it, but it's not something unexpected, really. MS'
compiler has been having troubles with templates and today isn't the
last day of it. I'll ask in microsoft.public.vc.language. Maybe they
already know of a bug reported on this...

V

I modified your codes and it passed.
------------------
#include <iostream>
using namespace std;

template <int L, int M, int T>
class Quantity
{
public:
Quantity(double d=0){};
template<int L1, int M1, int T1, int L2, int M2, int T2>
friend Quantity operator*
(const Quantity& q1,const Quantity& q2);
};

template<int L1, int M1, int T1, int L2, int M2, int T2>
Quantity<L1+L2,M1+M2,T1+T2> operator*
(const Quantity<L1,M1,T1>& q1,const Quantity<L2,M2,T2>& q2)
{
Quantity<L1+L2,M1+M2,T1+T2> q;
return q;
};

typedef Quantity<1,0,-2> Acceleration;
typedef Quantity<1,0,0> Length;

int main()
{
const Acceleration GRAV(9.81);
const Length penLen(1);
Quantity<2,0,-2> q(9);
q=GRAV*penLen;
return 0;
}
----------------------
The important change is the function declaration in the class:
friend Quantity operator*
(const Quantity& q1,const Quantity& q2);
We don't need to specify the template parameter here because we've
already done so in the class template declaration, and to the compiler,
all those Quantity<L1+L2,M1+M2,T1+T2>, Quantity<L2,M2,T2>.. are the
same as Quantity<L,M,T>.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top