Reputation: 3484
I created a class template (called ThreeVector
) and added functionality to allow the addition operation between different types. Here's the relevant portion of my header file:
template <class T>
class ThreeVector {
private:
T mx;
T my;
T mz;
public:
ThreeVector<T>(T, T, T);
template <class X>
ThreeVector<T> operator+(const ThreeVector<X>&);
}
template <class T>
ThreeVector<T>::ThreeVector(T x, T y, T z) { //initialize vector
mx = x;
my = y;
mz = z;
}
template<class T> template<class X>
ThreeVector<T> ThreeVector<T>::operator+(const ThreeVector<X>& a) {
ThreeVector<T> v(mx+a.mx, my+a.my, mz+a.mz);
return v;
}
And then I call it like this:
ThreeVector<double> a(1,2,3);
ThreeVector<float> b(4,5,6);
ThreeVector<double> c=a+b;
This gives me the error:
ThreeVector.h: In member function 'ThreeVector<T> ThreeVector<T>::operator+(const ThreeVector<X>&) [with X = float, T = double]':
ThreeVectorTest.cxx:33: instantiated from here
ThreeVector.h:8: error: 'float ThreeVector<float>::mx' is private
ThreeVector.h:122: error: within this context
ThreeVector.h:9: error: 'float ThreeVector<float>::my' is private
ThreeVector.h:123: error: within this context
ThreeVector.h:10: error: 'float ThreeVector<float>::mz' is private
ThreeVector.h:124: error: within this context
make: *** [ThreeVectorTest] Error 1
It works fine if both a and b are <double>
. Any idea why this happens?
Upvotes: 1
Views: 95
Reputation: 206667
The access privileges of class templates can be a little confusing.
Say you have a simple class template.
template <typename T>
class A
{
public:
A() {}
private:
T data;
};
When you create instances of A
using,
A<int> a1;
A<float> a2;
You are defining two classes using the template. It's as if you had two classes:
class AInt
{
public:
AInt() {}
private:
int data;
};
and
class AFloat
{
public:
AFloat() {}
private:
float data;
};
It's easy to see that AInt
doesn't have access to the private section of AFloat
and vice versa.
That is also true with A<int>
and A<float>
.
In order for you make your operator+
function work, you have two choices:
Have a friend declaration like:
template <class T>
class ThreeVector {
private:
T mx;
T my;
T mz;
public:
ThreeVector<T>(T, T, T);
template <class X>
ThreeVector<T> operator+(const ThreeVector<X>&);
template <class X> friend class ThreeVector;
};
Upvotes: 1