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
Solved

How to use overloaded operators in template class

Posted on 2002-05-22
12
254 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
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.

856 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