?
Solved

How to use overloaded operators in template class

Posted on 2002-05-22
12
Medium Priority
?
258 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

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

New benefit for Premium Members - Upgrade now!

Ready to get started with anonymous questions today? It's easy! Learn more.

Question has a verified solution.

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

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 how to use and create new code templates in NetBeans IDE 8.0 for Windows.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

765 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