Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

How to use overloaded operators in template class

Posted on 2002-05-22
12
Medium Priority
?
259 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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.

Question has a verified solution.

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

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

609 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