Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Operator overloading for template class
QtWS25 Last Chance

Operator overloading for template class

Scheduled Pinned Locked Moved C++ Gurus
15 Posts 4 Posters 5.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Nobody-86
    wrote on last edited by
    #3

    Hi,

    yes this looks similar to what I want to have. But, if I put these code inside my dvector.cpp file I get an error:
    undefined reference to 'operator+(DVector<float>&, DVector<float>&)' I sum two float vectors for testing).

    Also, this will work only (if it work) for the 4 overloadings int+int, float+float, double+double and complex+complex.
    there is no definition for different types eg. int+float.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mcosta
      wrote on last edited by
      #4

      Hi,

      template must be resolved at compile time.
      This means that you shall write all your code in header file or include your cpp file at the end of header

      Once your problem is solved don't forget to:

      • Mark the thread as SOLVED using the Topic Tool menu
      • Vote up the answer(s) that helped you to solve the issue

      You can embed images using (http://imgur.com/) or (http://postimage.org/)

      1 Reply Last reply
      0
      • N Offline
        N Offline
        Nobody-86
        wrote on last edited by
        #5

        Hi,

        I don't like to write the code in the header, becouse it will blow up the file and make it hard to read.

        Including the cpp file at the end of the header will results in multiple errors like:
        redefinition of 'DVector<TYPE>::DVector()' DVector<TYPE>::DVector()

        So I decide to put
        @
        template class DVector<int>;
        template class DVector<float>;
        template class DVector<double>;
        template class DVector<ComplexNumber>;
        @

        at the end of the cpp-file, as it is mentioned here:
        http://www.parashift.com/c++-faq-lite/separate-template-class-defn-from-decl.html

        this works fine for all constructors and methods, but it does not work for operator-overloading. I think it will work for operator too if it is done correctly, but I cant find my mistake.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mcosta
          wrote on last edited by
          #6

          Hi,

          are your 'operator+' functions members of DVector?
          If yes you must define it as
          @
          template <typename T>
          DVector<T> DVector<T>::operator+(....) {
          }
          @

          Anyway, if you read the STL sources you'll se that there's no separation between header and sources.
          Put all your code in header file could be a suitable solution

          Also if you have a look of streambuf header you'll see the source inclusion at the endo of file

          Once your problem is solved don't forget to:

          • Mark the thread as SOLVED using the Topic Tool menu
          • Vote up the answer(s) that helped you to solve the issue

          You can embed images using (http://imgur.com/) or (http://postimage.org/)

          1 Reply Last reply
          0
          • N Offline
            N Offline
            Nobody-86
            wrote on last edited by
            #7

            Hi,

            the operator+ function is not part of the DVector class
            eg:
            @
            class DVector
            {
            public:
            // ...
            private:
            // ...
            }

            DVector<int> operator+(DVector<int> &lhs, DVector<int> &rhs);
            // ...
            @

            As far as I know, it is not allowed to put operator-overloading inside the class. Please correct me if I am wrong.

            Is there a difference between a definition inside ther class and outside the class (but in the header file)?
            #1:
            @
            class test
            {
            void test()
            {
            // ...
            }
            }
            @

            #2:
            @
            class test
            {
            void test();
            }

            void DVector::test()
            {
            // ...
            }
            @

            I had a look at a streambuf.h file (http://opensource.apple.com/source/gcc/gcc-937.2/libio/streambuf.h), but it seems to me, that it is not the file you mean (can't find any definition at the end of the file)

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mcosta
              wrote on last edited by
              #8

              Hi,

              If I remember right (but I'm not sure), if you define your function inside class, the compiler try to compile as inline function.

              The header I means is the standard STL <streambuf> that (usually in /usr/include/c++/)

              Once your problem is solved don't forget to:

              • Mark the thread as SOLVED using the Topic Tool menu
              • Vote up the answer(s) that helped you to solve the issue

              You can embed images using (http://imgur.com/) or (http://postimage.org/)

              1 Reply Last reply
              0
              • N Offline
                N Offline
                Nobody-86
                wrote on last edited by
                #9

                Hi,

                now I have put my definition inside the header
                @
                // Overload the + operator
                template <typename TYPE>
                DVector<TYPE> operator+(DVector<TYPE> &lhs, DVector<TYPE> &rhs){
                if(lhs.getLength() != rhs.getLength()){
                throw 1;
                } else {
                DVector<TYPE> ret;
                for(unsigned int i=0; i<lhs.getLength(); ++i){
                ret.append(rhs.getData(i)+lhs.getData(i));
                }
                return ret;
                }
                }
                @

                and it workes fine for all types of the same type (eg. int+int, double+double ...). But if there are different types, it won't work. I tried to put this code also in the header:
                @
                template <typename TYPE1, typename TYPE2>
                DVector<TYPE1> operator+(DVector<TYPE1> &lhs, DVector<TYPE2> &rhs){
                if(lhs.getLength() != rhs.getLength()){
                throw 1;
                } else {
                DVector<TYPE1> ret;
                for(unsigned int i=0; i<lhs.getLength(); ++i){
                ret.append(rhs.getData(i)+lhs.getData(i));
                }
                return ret;
                }
                }
                @

                this will work for some type-combinations. (eg. double+int) but not for all (eg. int+double). This is becouse the compiler don't know that he should use always the "higher" type as solution (int+double=double and double+int=double).

                is there a way to tell him such a thing?

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  Arnaut
                  wrote on last edited by
                  #10

                  bq. is there a way to tell him such a thing?

                  I don't think there is.

                  Anyway you can drop the first function, the second one will also work when TYPE1 is equal to TYPE2.

                  For the remaining problems you can define explicitly the functions

                  @DVector<float> operator+( DVector<int> &lhs, DVector<float> &rhs)
                  {
                  return rhs + lhs;
                  }

                  DVector<double> operator+( DVector<int> &lhs, DVector<double> &rhs)
                  {
                  return rhs + lhs;
                  }

                  DVector<double> operator+( DVector<float> &lhs, DVector<double> &rhs)
                  {
                  return rhs + lhs;
                  }@

                  this will prevent the compiler from using template functions for those cases.

                  Hope it helps,
                  H.

                  1 Reply Last reply
                  0
                  • N Offline
                    N Offline
                    Nobody-86
                    wrote on last edited by
                    #11

                    Hi,

                    I tried this, but get an error:
                    multiple definition of `operator+(DVector<int>&, DVector<float>&)'

                    here is my code:
                    @
                    template<typename TYPE1, typename TYPE2>
                    DVector<TYPE1> operator+(DVector<TYPE1> &lhs, DVector<TYPE2> &rhs){
                    if(lhs.getLength() != rhs.getLength()){
                    throw 1;
                    }else{
                    DVector<TYPE1> ret;
                    for(unsigned int i=0; i<lhs.getLength(); ++i){
                    ret.append(lhs.getData(i)+rhs.getData(i));
                    }
                    return ret;
                    }
                    }

                    DVector<float> operator+(DVector<int> &lhs, DVector<float> &rhs){
                    return rhs+lhs;
                    }
                    @

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      Arnaut
                      wrote on last edited by
                      #12

                      Hi,

                      I tested it before my first post using Visual C++ 2010 and it works (just double checked it).

                      But to be honest I don't know what C++ Standard says about that.

                      Regards,
                      H.

                      1 Reply Last reply
                      0
                      • N Offline
                        N Offline
                        Nobody-86
                        wrote on last edited by
                        #13

                        Hi,

                        I haven't found a solution yet.

                        I addet a new feature to convert all types to others (wich work very well). With this new feature I had a new idea, making just one templatefunction for same type:
                        @
                        template<typename TYPE>
                        DVector<TYPE> operator+(DVector<TYPE> &lhs, DVector<TYPE> &rhs){
                        if(lhs.getLength() != rhs.getLength()){
                        throw 1;
                        }else{
                        DVector<TYPE> ret;
                        for(unsigned int i=0; i<lhs.getLength(); ++i){
                        ret.append(lhs.getData(i)+rhs.getData(i));
                        }
                        return ret;
                        }
                        }
                        @

                        This work also fine.
                        Next I start to write overloading for all the different types:
                        @
                        DVector<float> operator+(DVector<int> &lhs, DVector<float> &rhs){
                        return lhs.toFloat()+rhs;
                        }

                        DVector<float> operator+(DVector<float> &lhs, DVector<int> &rhs){
                        return lhs+rhs.toFloat();
                        }
                        // .....
                        @

                        But again, I get an error:
                        no match for 'operator+' (operand types are 'DVector<float>' and 'DVector<float>')
                        return lhs.toFloat()+rhs;

                        This is realy wired to me. If I add two float-vectors in the main.cpp this will work. But for operator-overloading it does not.

                        here is another wird thing:
                        @
                        // this work fine:
                        DVector<float> floatSum;
                        floatSum = floatVect + floatVect;

                        // this won't work:
                        DVector<float> intFloatSum;
                        intFloatSum = intVect.toFloat() + floatVect;
                        @

                        I get the same error:
                        no match for 'operator+' (operand types are 'DVector<float>' and 'DVector<float>')
                        intFloatSum = intVect.toFloat() + floatVect;

                        bwt: Thanks for all help so far!

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          Arnaut
                          wrote on last edited by
                          #14

                          Hi,

                          I don't know how you organized your code so I can't help you to find out what is wrong.

                          I would take the code you posted on April 20 and create the function
                          @template<typename TYPE1, typename TYPE2>
                          DVector<TYPE1> addDVectors(DVector<TYPE1> &lhs, DVector<TYPE2> &rhs){
                          static_assert( sizeof( TYPE1 ) >= sizeof( TYPE2 ), "precondition sizeof( TYPE1 ) >= sizeof( TYPE2 ) failed. Invert the parameters order!" );
                          if(lhs.getLength() != rhs.getLength()){
                          throw 1;
                          }else{
                          DVector<TYPE1> ret;
                          for(unsigned int i=0; i<lhs.getLength(); ++i){
                          ret.append(lhs.getData(i)+rhs.getData(i));
                          }
                          return ret;
                          }
                          }
                          @

                          you still need to implement each of the 16 versions of operator '+' by hand but now they are all one line long.

                          Hope it helps,
                          H.

                          PS. On that static assertive I'm assuming that sizeof( ComplexNumber ) > sizeof( double )

                          1 Reply Last reply
                          0
                          • N Offline
                            N Offline
                            Nobody-86
                            wrote on last edited by
                            #15

                            Hi,
                            thanks Arnaut,I finally bring all the operator overloading DVector<X> * DVector<Y> to work.
                            But, there is a new wired thing.
                            I also implement a operator overloading for DVector<X> * <Y>, where Y is of different Types (int, float, double, ComplexNumber). Here is my code:
                            @
                            // inside the class (*.h)
                            // multiply a constant value.
                            template<typename OTHERTYPE>
                            DVector<TYPE> multiply(OTHERTYPE other){
                            DVector<TYPE> ret;
                            for(unsigned int i=0; i<getLength(); ++i){
                            ret.append(getData(i)*other);
                            }
                            return ret;
                            }

                            // also inside .h but outside the class
                            DVector<int> operator
                            (DVector<int> &lhs, int &rhs);

                            // inside .cpp
                            DVector<int> operator
                            (DVector<int> &lhs, int &rhs){
                            return lhs.multiply(rhs);
                            }
                            @

                            This will work fine if I write:
                            @
                            DVector<int> intVect;
                            DVector<int> intVect3;
                            int test = 3;
                            intVect3 = intVect*test;
                            @

                            But (and this is wired for me) this won't work:
                            @
                            DVector<int> intVect;
                            DVector<int> intVect3;
                            intVect3 = intVect*3;
                            @

                            I get this error:
                            no match for 'operator*' (operand types are 'DVector<int>' and 'int')
                            intVect3 = intVect*3;

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved