Hello,
It's been a while since I've worked in C++, so I got a little stuck. Here's a simplified version of my problem.
I have a templatized class called A which has a data member called "data".
I'm trying to overload the * operator (multiplication) for it. I want it to be possible to multiply this class with another instance of the same class. So "A<int> times A<int>" should be possible.
But I also want it to be possible to multiple the class with a constant (like an int or a double) instead of a class. So "A<int> times float" should also be possible.
All works fine so far when I have just this much defined:
template<class T>
class A
{
public:
// Data member
T data;
// Constructors
A<T>()
{
this->data = T();
}
A<T>(T new_data)
{
this->data = new_data;
}
// Multiply an instance of A<T> with another instance of A<T>
A<T> operator*(A<T>& rhs)
{
cout << "Performing A<T> times A<T>" << endl;
return A<T>(this->data * rhs.data);
}
// Multiply an instance of A<T> with some other data type
template<class V>
A<T> operator*(V c)
{
cout << "Performing A<T> times V" << endl;
return A<T>(this->data * c);
}
};
Here's some test code:
// Initialize some test numbers
A<int> a1(5);
A<int> a2(7);
double b1 = 4.7;
// Perform the operations
A<int> a3 = a1 * a2; // Causes to print: "Performing A<T> times A<T>"
A<int> a4 = a1 * b1; // Causes to print: "Performing A<T> times V"
// Print the results
cout << a3.data << endl; // Prints 35
cout << a4.data; // Prints 23 (not 23.5 because a2 is parameterized with "int" instead of "double" but oh well)
But I want to add another layer of complexity, which is where I encounter some problems. I introduce another class B which is derived from A<T>:
template<class T>
class B : public A<T>
{
public:
// Constructor
B<T>(T new_data)
{
this->data = new_data;
}
};
Now suppose I do this:
A<int> a1(5);
B<int> b1(12);
A<int> a2 = a1 * b1;
cout << a2.data;
The compiler will give an error:
Error C2677: binary '*' : no global operator found which takes type 'B<T>' (or there is no acceptable conversion)
The error is in the function
template<class V> A<T> operator*(V c)
Apparently, what happens when I try to perform a1 * b1, the compiler picks the wrong operator* function. I want it to pick the first one ("Multiply an instance of A<T> with another instance of A<T>") because B<T> is derived from A<T>. But the compiler picks the second one ("Multiply an instance of A<T> with some other data type"), I guess because B<T> is not
exactly A<T>, and the second operator* function is the general catch-all one.
What can I do in this case? I want the compiler to pick the first operator* function when I multiple an A<T> type with a B<T> type.
(Second bonus question: How might I make it possible to multiple A<int> with A<double>? At the moment, the 'T' parameter has to match when I multiply one instance of A<T> with another instance of A<T>.)
EDIT: Here's the complete code, which doesn't compile due to the one error described above:
#include <iostream>
using namespace std;
template<class T>
class A
{
public:
// Data member
T data;
// Constructors
A<T>()
{
this->data = T();
}
A<T>(T new_data)
{
this->data = new_data;
}
// Multiply an instance of A<T> with another instance of A<T>
A<T> operator*(A<T>& rhs)
{
cout << "Performing A<T> times A<T>" << endl;
return A<T>(this->data * rhs.data);
}
// Multiply an instance of A<T> with some other data type
template<class V>
A<T> operator*(V c)
{
cout << "Performing A<T> times V" << endl;
return A<T>(this->data * c);
}
};
template<class T>
class B : public A<T>
{
public:
// Constructor
B<T>(T new_data)
{
this->data = new_data;
}
};
int main()
{
A<int> a1(5);
B<int> b1(12);
A<int> a2 = a1 * b1;
cout << a2.data;
cin.get();
return 0;
}