Solved

How to use overloaded operators in template class

Posted on 2002-05-22
12
256 Views
Last Modified: 2013-12-14
Hi

I am in the process of converting a simple C++ library into a template-based form, but have hit a snag on operators.  Rather than present the whole library (!), the problem can be shown easily in a simple snippet below, which fails to compile.  I'm also having similar difficulty using friend operators within the template class.  All the template-based functions work fine.

The following fails to compile with errors on the two operators (+ and =) when using the g++ compiler.  The simple print() and put() work fine if the operator-related parts of the code are deleted.

Thank you.
----------------------------------------------

// Very very simple template class
#include <iostream>
#include <cstdlib>
using namespace std;

template <class MyType> class simple {
   MyType a;
public:
   put(MyType inval);
   print();
   MyType operator+(simple op);
   MyType operator=(simple op);
};

// Put value
template <class MyType> simple<MyType>::put(MyType inval)
{
   a = inval;
}

// Print value
template <class MyType> simple<MyType>::print()
{
   cout << "\nThe value of a is " << a << "\n";
}

// Add together two objects (does not work)
template <class MyType> MyType simple<MyType>::operator+(simple op)
{
   simple temp;

   temp.a = op.a + a;
   return a;
}

// Overload = sign (does not work)
template <class MyType> MyType simple<MyType>::operator=(simple op)
{
   a = op.a;

   return *this;
}

// Off we go...
int main()
{
   simple<int> intobject1;
   simple<int> intobject2;
   simple<int> intobject3;

   intobject1.put(5);
   intobject2.put(6);

   intobject1.print();
   intobject2.print();

   intobject3 = intobject1 + intobject2;

   intobject3.print();

   return 0;
}
0
Comment
Question by:doyston
  • 7
  • 3
  • 2
12 Comments
 
LVL 3

Expert Comment

by:MDarling
ID: 7027245
#include <iostream>
#include <cstdlib>

using namespace std;

template <class MyType> class simple {
    MyType a;
public:

    simple()
        {
        }

    simple(const simple<MyType>& x)
        {
            a=x.a;
        }

    void put(MyType inval);
    void print();
    simple<MyType> operator+(const simple& op);
    simple<MyType>& operator=(const simple& op);


};

// Put value
template <class MyType>
void simple<MyType>::put(MyType inval)
{
    a = inval;
}

// Print value
template <class MyType>
void simple<MyType>::print()
{
    cout << "\nThe value of a is " << a << "\n";
}

// Add together two objects (does not work)
template <class MyType>
simple<MyType> simple<MyType>::operator+(const simple& op)
{
    simple<MyType> temp;
    temp.a=this->a + op.a;
    return temp;
}

// Overload = sign (does not work)
template <class MyType>
simple<MyType>& simple<MyType>::operator=(const simple& op)
{
    a = op.a;
    return *this;
}

// Off we go...
int main()
{
    simple<int> intobject1;
    simple<int> intobject2;
    simple<int> intobject3;
    intobject1.put(5);
    intobject2.put(6);
    intobject1.print();
    intobject2.print();
    intobject3 = intobject1 + intobject2;
    intobject3.print();
    return 0;
}

0
 
LVL 3

Expert Comment

by:MDarling
ID: 7027254
code modified above to compile.

You were mistakenly returning MyType in some cases instead of the template class object you really wanted to return.

Notice the use of const references as well in some cases on params.

Also notice I created a default constructor and a copy constructor to enable the assignment to work.

Regards,
Mike
0
 
LVL 3

Expert Comment

by:MDarling
ID: 7027255
code modified above to compile.

You were mistakenly returning MyType in some cases instead of the template class object you really wanted to return.

Notice the use of const references as well in some cases on params.

Also notice I created a default constructor and a copy constructor to enable the assignment to work.

Regards,
Mike
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:ambience
ID: 7028797
#include <iostream>
#include <cstdlib>
using namespace std;

template <class MyType> class simple
{
  MyType a;

public:
  simple<MyType>(){}
  simple<MyType>(MyType b) { a = b; }
  simple<MyType>(simple<MyType> b) { a = b.a; }
 
  void put(MyType inval);
  void print();

  // Maybe you wanted to return MyType here
  // if yes then the second constructor is required
  // otherwise you can return simple<MyType> as given in
  // another solution above

  MyType operator+(const simple<MyType>& op);
  simple<MyType> operator=(const simple<MyType>& op);
};

// Put value
template <class MyType>
void simple<MyType>::put(MyType inval)
{
  a = inval;
}

// Print value
template <class MyType>
void simple<MyType>::print()
{
  cout << "\nThe value of a is " << a << "\n";
}

// Add together two objects (does not work)
template <class MyType>
MyType simple<MyType>::operator+(const simple<MyType>& op)
{
  simple<MyType> temp;
  temp.a = op.a + a;
  return temp.a;
}

// Overload = sign (does not work)
template <class MyType>
simple<MyType> simple<MyType>::operator=(const simple<MyType>& op)
{
  a = op.a;
  return *this;
}

// Off we go...
int main()
{
  simple<int> intobject1;
  simple<int> intobject2;
  simple<int> intobject3;

  intobject1.put(5);
  intobject2.put(6);

  intobject1.print();
  intobject2.print();

  intobject3 = intobject1 + intobject2;
  intobject3.print();
  return 0;
}


hope this helps
0
 
LVL 22

Expert Comment

by:ambience
ID: 7028801
sorry for one thing

simple<MyType>(simple<MyType> b) { a = b.a; }

should've been

simple<MyType>(const simple<MyType>& b) { a = b.a; }
 


0
 

Author Comment

by:doyston
ID: 7029198
Thank you both for your help; program now compiles properly.  I should have spotted my mistake when I tried to return MyType instead of the template class itself.  I notice that you've slightly altered the layout of the code, which makes it much more readable, and the logic is now clearer.

I'm still hitting a snag when I try and include a friend function, however.  For example, if I want to overload the + operator so that it can do an object + integer addition, I've tried putting:

friend simple<MyType> operator+(const simple &op1, const int &op2);

within the public definition of the simple class, and then further down the code put:

// Overload + as friend
template <class MyType>
simple<MyType> operator+(const simple &op1, const int &op2)
{
   simple<MyType> temp;

   temp.a = op1.a + op2;

   return temp;
}

This generates all sorts of compilation errors on g++, including warnings about the friend declaration declaring a non-template declaration, and the need to add <> after the function name, which I don't really understand, and it then gets confused by the number of arguments expected for the friend function.  The compiler states that it must be one or two (I thought it was two according to the code).

I'm obviously making some silly mistake here, but haven't got the hang of these templates yet.

Thanks again for your help.
Roy
0
 
LVL 3

Expert Comment

by:MDarling
ID: 7029237
look at your parameters to the function....

Regards,
Mike.
0
 
LVL 3

Expert Comment

by:MDarling
ID: 7029249
template <class MyType>
simple<MyType> operator+(const simple<MyType> &op1, const int &op2)
{
  simple<MyType> temp;
  temp.a = op1.a + op2;
  return temp;
}

Regards,
Mike.
0
 

Author Comment

by:doyston
ID: 7029342
Thanks, but I'm still hitting similar compilation problems.  Lots of warnings about the friend declaration being a non-template type, then followed by the line:

/tmp/ccDf55h1.o: In function'main':
/tmp/ccDf55h1.o (.text+0x72): undefined reference to 'operator+(simple<int> const &, int const &)'

which I guess is some sort of linker error when it hits the line

intobject3 = intobject2 + 10;

in main.  This is being run on RHL 6.0.
Roy
0
 
LVL 3

Expert Comment

by:MDarling
ID: 7029369
The reason is you are creating a specialisation for simple<int>

your need to define the friend function for each specialisation you use.

see below...

0
 
LVL 3

Accepted Solution

by:
MDarling earned 300 total points
ID: 7029372
#include <iostream>
#include <cstdlib>

using namespace std;

template <class MyType> class simple {
    MyType a;
public:

    simple()
        {
        }

    simple(const simple<MyType>& x)
        {
            a=x.a;
        }

    void put(MyType inval);
    void print();
    simple<MyType> operator+(const simple& op);
    simple<MyType>& operator=(const simple& op);

    friend simple<MyType> operator+(const simple<MyType>& op1,int op2);
};

// Put value
template <class MyType>
void simple<MyType>::put(MyType inval)
{
    a = inval;
}

// Print value
template <class MyType>
void simple<MyType>::print()
{
    cout << "\nThe value of a is " << a << "\n";
}

// Add together two objects
template <class MyType>
simple<MyType> simple<MyType>::operator+(const simple& op)
{
    simple<MyType> temp;
    temp.a=this->a + op.a;
    return temp;
}

// Overload = sign
template <class MyType>
simple<MyType>& simple<MyType>::operator=(const simple& op)
{
    a = op.a;
    return *this;
}


// specialisation for simple<int>
simple<int> operator+(const simple<int>& op1, int op2)
{
    simple<int> temp;
    temp.a = op1.a + op2;
    return temp;
}

// Off we go...
int main()
{
    simple<int> intobject1;
    simple<int> intobject2;
    simple<int> intobject3;
    intobject1.put(5);
    intobject2.put(6);
    intobject1.print();
    intobject2.print();
    intobject3 = intobject1 + intobject2;
    intobject3.print();
    intobject3 = intobject2 + 10;
    return 0;
}



0
 

Author Comment

by:doyston
ID: 7029821
Excellent!  I think I now understand what's going on, as I hadn't through the implications of the friend function being outside the MyType template.

Thank you very much for your help.
Roy
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
is twain_32.dll cmpatible with windows 10 ? 10 233
best sources to up-to-date in C++? 8 103
oracle 11g 23 128
FMX TEdit KeyUp handler detecting  "enter" key 4 39
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Here is a helpful source code for C++ Builder programmers that allows you to manage and manipulate HTML content from C++ code, while also handling HTML events like onclick, onmouseover, ... Some objects defined and used in this source include: …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question