Templates and helpers.

Discussion in 'C++' started by Magnus Jonneryd, Oct 6, 2005.

  1. I want to be able to define a super class that defines some basic functionality
    and also some helpers that define, mainly, arithmetic operations, but I've been
    having some trouble.

    The following example illustrates what i want to do:

    template<typename T = int>
    class A{};

    template<typename T = int>
    class B: public A<T>{};

    template<typename T>
    A<T> operator*(const A<T>& lhs, const A<T>& rhs){
    return lhs;
    }

    int main(){
    B<> b_1;
    B<> b_2;
    B<> b_3;
    b_3 = b_1*b_2;
    }

    But when I compile it I get the following:
    tst.cc: In function `int main()':
    tst.cc:16: error: no match for 'operator=' in 'b_3 = operator* [with T
    =int](((const A<int>&)((const A<int>*)((A<int>*)(&b_1)))), ((const A<int>&)
    ((const A<int>*)((A<int>*)(&b_2)))))'
    tst.cc:5: note: candidates are: B<int>& B<int>::eek:perator=(const B<int>&)

    Which I think means that the assignment operator ain't defined so that it's possible
    to assign an instance of class A to class B. I was hoping that the inheritance would
    make this possible, but alas.

    What i then did was to define the operator as:
    template<typename T>
    T operator*(const T& lhs, const T& rhs){
    return lhs;
    }

    Which works, but won't this cause a problem if i try multiplying something else
    since this is quite a general solution? What I wanted to do was to be able to just
    add some functionality in my sub-classes and be able to use the helpers that i
    defined in the super class, and be able to use the same scheme with another
    set of classes (i.e D: public D). But if i do that won't that mean that the two
    functions will "collide"?

    Thanks in advance.
    --
    (Should insert humorous quotation here)
    Magnus Jonneryd, Oct 6, 2005
    #1
    1. Advertising

  2. Magnus Jonneryd wrote:
    > I want to be able to define a super class that defines some basic functionality
    > and also some helpers that define, mainly, arithmetic operations, but I've been
    > having some trouble.
    >
    > The following example illustrates what i want to do:
    >
    > template<typename T = int>
    > class A{};
    >
    > template<typename T = int>
    > class B: public A<T>{};
    >
    > template<typename T>
    > A<T> operator*(const A<T>& lhs, const A<T>& rhs){
    > return lhs;
    > }
    >
    > int main(){
    > B<> b_1;
    > B<> b_2;
    > B<> b_3;
    > b_3 = b_1*b_2;
    > }
    >
    > But when I compile it I get the following:
    > tst.cc: In function `int main()':
    > tst.cc:16: error: no match for 'operator=' in 'b_3 = operator* [with T
    > =int](((const A<int>&)((const A<int>*)((A<int>*)(&b_1)))), ((const A<int>&)
    > ((const A<int>*)((A<int>*)(&b_2)))))'
    > tst.cc:5: note: candidates are: B<int>& B<int>::eek:perator=(const B<int>&)


    This isn't going to work even without templates. There is no assignment
    operator in B that takes A as its argument.

    > Which I think means that the assignment operator ain't defined so that it's possible
    > to assign an instance of class A to class B.


    Yep. Templates have nothing to do with it.

    > I was hoping that the inheritance would
    > make this possible, but alas.


    It never does.

    > What i then did was to define the operator as:
    > template<typename T>
    > T operator*(const T& lhs, const T& rhs){
    > return lhs;
    > }
    >
    > Which works, but won't this cause a problem if i try multiplying something else
    > since this is quite a general solution?


    Yes, any other user-defined type suddenly has operator* defined for it.

    > What I wanted to do was to be able to just
    > add some functionality in my sub-classes and be able to use the helpers that i
    > defined in the super class, and be able to use the same scheme with another
    > set of classes (i.e D: public D). But if i do that won't that mean that the two
    > functions will "collide"?


    I don't understand what functions will collide. If you define the
    required assignment operator (and define it as doing the right thing),
    what should collide with what?

    V
    Victor Bazarov, Oct 6, 2005
    #2
    1. Advertising

  3. Victor Bazarov wrote:

    > Magnus Jonneryd wrote:
    >> I want to be able to define a super class that defines some basic
    >> functionality and also some helpers that define, mainly, arithmetic
    >> operations, but I've been having some trouble.
    >>
    >> The following example illustrates what i want to do:
    >>
    >> template<typename T = int>
    >> class A{};
    >>
    >> template<typename T = int>
    >> class B: public A<T>{};
    >>
    >> template<typename T>
    >> A<T> operator*(const A<T>& lhs, const A<T>& rhs){
    >> return lhs;
    >> }
    >>
    >> int main(){
    >> B<> b_1;
    >> B<> b_2;
    >> B<> b_3;
    >> b_3 = b_1*b_2;
    >> }
    >>
    >> But when I compile it I get the following:
    >> tst.cc: In function `int main()':
    >> tst.cc:16: error: no match for 'operator=' in 'b_3 = operator*
    >> [with T =int](((const A<int>&)((const
    >> A<int>*)((A<int>*)(&b_1)))), ((const A<int>&) ((const
    >> A<int>*)((A<int>*)(&b_2)))))' tst.cc:5: note: candidates are:
    >> B<int>& B<int>::eek:perator=(const B<int>&)

    >
    > This isn't going to work even without templates. There is no assignment
    > operator in B that takes A as its argument.
    >
    >> Which I think means that the assignment operator ain't defined so that
    >> it's possible to assign an instance of class A to class B.

    >
    > Yep. Templates have nothing to do with it.
    >
    >> I was hoping that the inheritance would
    >> make this possible, but alas.

    >
    > It never does.
    >
    >> What i then did was to define the operator as:
    >> template<typename T>
    >> T operator*(const T& lhs, const T& rhs){
    >> return lhs;
    >> }
    >>
    >> Which works, but won't this cause a problem if i try multiplying
    >> something else since this is quite a general solution?

    >
    > Yes, any other user-defined type suddenly has operator* defined for it.
    >
    > > What I wanted to do was to be able to just
    >> add some functionality in my sub-classes and be able to use the helpers
    >> that i defined in the super class, and be able to use the same scheme
    >> with another set of classes (i.e D: public D). But if i do that won't
    >> that mean that the two functions will "collide"?

    >
    > I don't understand what functions will collide. If you define the
    > required assignment operator (and define it as doing the right thing),
    > what should collide with what?
    >
    > V


    Uhm, nevermind about the "collision" bit, I was just rambling. But as a
    follow-up question: If i define an assignment operator, like so:

    B<T> operator=(const A<T>& a){
    if(this==&a)
    return *this;

    return B<T>(a);
    }

    How come it's possible to assign like this:
    B<> b;
    B<> b_1;
    b = b_1;

    As far as i can tell The class B inherits from A making it possible to make
    the function call but since I don't know if it's the call: B = B or
    B = A; I can't assign the extra information in B (if it's a case of B = B)
    ,on the left hand side, which means I loose some information every time i
    use the operator. Is this correct or am I just rambling on again?

    Thanks again.
    --
    (Should insert humorous quotation here)
    Magnus Jonneryd, Oct 6, 2005
    #3
  4. Magnus Jonneryd wrote:
    > [...] a
    > follow-up question: If i define an assignment operator, like so:
    >
    > B<T> operator=(const A<T>& a){
    > if(this==&a)
    > return *this;
    >
    > return B<T>(a);
    > }
    >
    > How come it's possible to assign like this:
    > B<> b;
    > B<> b_1;
    > b = b_1;


    The user-defined assignment from A<T> *overloads* the compiler-defined
    assignment from B.

    > As far as i can tell The class B inherits from A making it possible to make
    > the function call but since I don't know if it's the call: B = B or
    > B = A; I can't assign the extra information in B (if it's a case of B = B)
    > ,on the left hand side, which means I loose some information every time i
    > use the operator. Is this correct or am I just rambling on again?


    I don't know if you're rambling. Define the copy-assignment operator
    and see which one is called when. Yes, you don't know whether the A<T>
    is part of another B or of something completely different. That's why
    A<T> is the only thing you can rely upon. The other stuff (data beyond
    A<T> in 'this' B) has to either be kept as is (which is better) or
    made up from scratch.

    V
    Victor Bazarov, Oct 6, 2005
    #4
  5. Victor Bazarov wrote:

    > Magnus Jonneryd wrote:
    >> [...] a
    >> follow-up question: If i define an assignment operator, like so:
    >>
    >> B<T> operator=(const A<T>& a){
    >> if(this==&a)
    >> return *this;
    >>
    >> return B<T>(a);
    >> }
    >>
    >> How come it's possible to assign like this:
    >> B<> b;
    >> B<> b_1;
    >> b = b_1;

    >
    > The user-defined assignment from A<T> *overloads* the compiler-defined
    > assignment from B.
    >
    >> As far as i can tell The class B inherits from A making it possible to
    >> make the function call but since I don't know if it's the call: B = B or
    >> B = A; I can't assign the extra information in B (if it's a case of B =
    >> B) ,on the left hand side, which means I loose some information every
    >> time i use the operator. Is this correct or am I just rambling on again?

    >
    > I don't know if you're rambling. Define the copy-assignment operator
    > and see which one is called when. Yes, you don't know whether the A<T>
    > is part of another B or of something completely different. That's why
    > A<T> is the only thing you can rely upon. The other stuff (data beyond
    > A<T> in 'this' B) has to either be kept as is (which is better) or
    > made up from scratch.
    >
    > V


    Thanks, I think that straightened it out.
    --
    (Should insert humorous quotation here)
    Magnus Jonneryd, Oct 6, 2005
    #5
    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. JKop
    Replies:
    3
    Views:
    455
  2. recover
    Replies:
    2
    Views:
    790
    recover
    Jul 25, 2006
  3. Caspar Bl

    gems, helpers and rails

    Caspar Bl, Aug 13, 2006, in forum: Ruby
    Replies:
    2
    Views:
    122
    Caspar Bl
    Aug 13, 2006
  4. Becca Girl
    Replies:
    0
    Views:
    91
    Becca Girl
    Jul 27, 2007
  5. Gerald Bauer
    Replies:
    0
    Views:
    109
    Gerald Bauer
    Feb 25, 2009
Loading...

Share This Page