overloaded friend operators in template class

D

desalvo123

This compile and works fine.

Example 1:
---------------------
class MyDouble
{
public:
MyDouble(double val) { m_Value = val; };
friend MyDouble operator + (const MyDouble&, const MyDouble&);

private:
double m_Value;
};

MyDouble operator + (const MyDouble &left, const MyDouble &right)
{
return MyDouble(left.m_Value + right.m_Value);
}
---------------------

But I can't figure out how to do the same thing in a template class.
I've tried Example 2 but it won't compile. I am using Visual Studio
..NET 2003.
If I take out the <> in the declartion of the operator + it compiles
but then if I try to use that operator I get an unresolved external
symbol error.

Example 2:
---------------------
template <class T> class MyDouble
{
public:
MyDouble<T>(T val) { m_Value = val; };
friend MyDouble<T> operator + <>(const MyDouble&, const MyDouble&);

private:
T m_Value;
};

template <class T> MyDouble<T> operator + (const MyDouble<T> &left,
const MyDouble<T> &right)
{
return MyDouble<T>(left.m_Value + right.m_Value);
}
---------------------
 
P

Peter Julian

This compile and works fine.

Example 1:
---------------------
class MyDouble
{
public:
MyDouble(double val) { m_Value = val; };
friend MyDouble operator + (const MyDouble&, const MyDouble&);

private:
double m_Value;
};

MyDouble operator + (const MyDouble &left, const MyDouble &right)
{
return MyDouble(left.m_Value + right.m_Value);
}
---------------------

But I can't figure out how to do the same thing in a template class.
I've tried Example 2 but it won't compile. I am using Visual Studio
.NET 2003.
If I take out the <> in the declartion of the operator + it compiles
but then if I try to use that operator I get an unresolved external
symbol error.

Example 2:
---------------------
template <class T> class MyDouble
{
public:
MyDouble<T>(T val) { m_Value = val; };
friend MyDouble<T> operator + <>(const MyDouble&, const MyDouble&);

private:
T m_Value;
};

template <class T> MyDouble<T> operator + (const MyDouble<T> &left,
const MyDouble<T> &right)
{
return MyDouble<T>(left.m_Value + right.m_Value);
}

Binary operator+ returns a const value. ctor should rely on the
initialization list.

template <class T>
class MyDouble
{
T m_value;
public:
MyDouble(T val) : m_value(val) { };
~MyDouble() { }

friend const MyDouble<T> /* operator+ */
operator+(const MyDouble<T>&, const MyDouble<T>&);
};

template <class T>
const MyDouble<T> /* operator+ */
operator+(const MyDouble<T>& left, const MyDouble<T>& right)
{
return MyDouble<T>(left.m_value + right.m_value);
}

int main()
{
MyDouble<double> md0(1.1);
MyDouble<double> md1(2.2);

MyDouble<double> md_result = md0 + md1;

return 0;
}
 
D

desalvo123

I tried you code but I still get an unresolved symbol error.

error LNK2001: unresolved external symbol "class MyDouble<double> const
__cdecl operator+(class MyDouble<double> const &,class MyDouble<double>
const &)"
 
P

Peter Julian

I tried you code but I still get an unresolved symbol error.

error LNK2001: unresolved external symbol "class MyDouble<double> const
__cdecl operator+(class MyDouble<double> const &,class MyDouble<double>
const &)"

Its telling you it can't find the supplied prototype's implementation. Have
you tried cleaning and rebuilding the project? Are you running the project
in debug without the dedug dlls (a known VS.net issue)? Are you seperating
declaration and implementation of MyDouble? If yes, can you post what you
ran exactly?

I ran the aforementioned code with VS, g++ and checked with comeau's online
compiler (which found one error which should be inconsequential):

MyDouble(T val) : m_value(val) { }; << extra semicolon

the ctor should have been:

MyDouble(T val) : m_value(val) { }

Here is the code using a seperate header for MyDouble class and the friend
functions are implemented without protyping (in case your compiler has a bug
with such template-friend prototypes):

________MyDouble.h____________

/* MyDouble.h ... MyDouble class */
#ifndef MYDOUBLE_H_
#define MYDOUBLE_H_

template <class T>
class MyDouble
{
T m_value;
public:
MyDouble(T val) : m_value(val) { }
~MyDouble() { }

// friend operator+
friend const MyDouble<T> /* rearranged to fit screen width */
operator+(const MyDouble<T>& left, const MyDouble<T>& right)
{
return MyDouble<T>(left.m_value + right.m_value);
}

// friend operator<<
friend std::eek:stream& /* rearranged to fit screen width */
operator<<(std::eek:stream& os, const MyDouble<T>& d)
{
os << d.m_value;
return os;
}
}; // class MyDouble

#endif // MYDOUBLE_H_ include guard

__________ Proj_Test.cpp___________

// Proj_Test.cpp.
//
#include <iostream>
#include "MyDouble.h"

int main()
{
MyDouble<double> md0(1.1);
std::cout << "md0 = " << md0 << "\n";
MyDouble<double> md1(2.2);
std::cout << "md1 = " << md1 << "\n";

MyDouble<double> md_result = md0 + md1;

std::cout << "result = " << md_result << "\n";

return 0;
}

/* output

md0 = 1.1
md1 = 2.2
result = 3.3

*/
 
D

desalvo123

Yes, that works, but it is different then my example. My problem
occurs if the functions are defined outside the class, like I showed in
my first post.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top