How to overload operator* for this template?

Discussion in 'C++' started by Atlas, Oct 14, 2005.

  1. Atlas

    Atlas Guest

    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.
     
    Atlas, Oct 14, 2005
    #1
    1. Advertising

  2. Atlas

    mlimber Guest

    Atlas wrote:
    > 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
     
    mlimber, Oct 14, 2005
    #2
    1. Advertising

  3. Atlas

    mlimber Guest

    Atlas wrote:
    > 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
     
    mlimber, Oct 14, 2005
    #3
  4. Atlas wrote:
    > 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<L1+L2,M1+M2,T1+T2> operator*( ...

    > ....
    > };
    >
    > 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
     
    Victor Bazarov, Oct 14, 2005
    #4
  5. Atlas

    Atlas Guest

    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.


    Victor Bazarov wrote:
    > Atlas wrote:
    > > 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<L1+L2,M1+M2,T1+T2> operator*( ...
    >
    > > ....
    > > };
    > >
    > > 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
     
    Atlas, Oct 15, 2005
    #5
  6. Atlas

    mlimber Guest

    Atlas wrote:
    > 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
     
    mlimber, Oct 17, 2005
    #6
  7. Atlas

    Atlas Guest

    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.
     
    Atlas, Oct 17, 2005
    #7
  8. Atlas

    Atlas Guest

    This time, the quoted text simply disappeared!
     
    Atlas, Oct 17, 2005
    #8
  9. Atlas

    mlimber Guest

    Atlas wrote:
    > 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
     
    mlimber, Oct 17, 2005
    #9
  10. Atlas

    mlimber Guest

    Atlas wrote:
    > 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
     
    mlimber, Oct 17, 2005
    #10
  11. mlimber wrote:
    >>Victor's codes are google example to expain my question.

    >
    >
    > Huh?


    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
     
    Victor Bazarov, Oct 17, 2005
    #11
  12. Atlas

    mlimber Guest

    Victor Bazarov wrote:
    > mlimber wrote:
    > >>Victor's codes are google example to expain my question.

    > >
    > >
    > > Huh?

    >
    > 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
     
    mlimber, Oct 17, 2005
    #12
  13. Atlas

    Atlas Guest

    mlimber wrote:
    > Victor Bazarov wrote:
    > > mlimber wrote:
    > > >>Victor's codes are google example to expain my question.
    > > >
    > > >
    > > > Huh?

    > >
    > > 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

    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.
     
    Atlas, Oct 20, 2005
    #13
  14. Atlas

    Atlas Guest

    Victor Bazarov wrote:
    > Atlas wrote:
    > > 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<L1+L2,M1+M2,T1+T2> operator*( ...
    >
    > > ....
    > > };
    > >
    > > 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


    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>.
     
    Atlas, Oct 20, 2005
    #14
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Piotre Ugrumov
    Replies:
    3
    Views:
    392
    Nick Hounsome
    Jan 25, 2004
  2. Fei Liu
    Replies:
    5
    Views:
    372
    Maxim Yegorushkin
    Feb 25, 2006
  3. fungus
    Replies:
    11
    Views:
    593
    fungus
    Jan 6, 2007
  4. Replies:
    1
    Views:
    521
    Ian Collins
    Apr 25, 2007
  5. Ying-Chieh Liao

    function overload (not operator overload)

    Ying-Chieh Liao, Oct 11, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    277
    Sherm Pendley
    Oct 11, 2004
Loading...

Share This Page