This is my first post. I have spent hours checking for a solution on my problem, searching link after link on SO, but none descried my problem exactly(the closest i could get were this and this). So, let's get to work!
Description: I must implement a collection of specialized classes, each one able to store a linked list of its type. Also (the tricky part), I must implement a collection manager, in a way that adding more specialized classes to the collection does not affect its code.
Let me explain what I have so far.
class IList {
public:
virtual IList& operator+( IList&) = 0;
virtual void print() = 0;
virtual int g_Size() const = 0;
//perfect till here
virtual void Push(const int&) = 0;//needs to be upgraded
virtual const int& operator[](int index) = 0;//needs to be upgraded
};
template<class T>
class Queue: public IList{
//internal stuff
public:
Queue();
int g_Size() const;
void print();
void Push(const T& cv);
const T& operator[](int index);
~Queue();
};//all implementation of Queue<T> is implemented and working, but removed for simplicity
class CIntList : public Queue<int>{
//stuff here, specialized on int
};
class C_Manager{
IList * classes[3];//notice the polymorphism, managing the class collection using a pointer to the common(base) interface
public:
void testing()
{
for (int i = 0; i < 3; i++)
classes[i] = new CIntList(i);
classes[0]->Push(1); classes[0]->Push(2); classes[1]->Push(1121); classes[2]->Push(12);
classes[0]->print();
classes[2]->print();
int a = classes[0]->operator[](1);
classes[1]->Push(a + a);
} //working fine
};
OK, so you`ll maybe ask, what is the question?
I do not want to redeclare the Push
and operator[]
(or any other function that uses the template as argument) for all of my classes specializations. More exactly, if I want to add, let's say,
class CFloatList: public Queue<float>
{
//float stuff goes here
};
I must also modify IList
to
class IList {
public:
virtual IList& operator+( IList&) = 0;
virtual void print() = 0;
virtual int g_Size() const = 0;
//perfect till here
virtual void Push(const int&) = 0;//used for int
virtual const int& operator[](int index) = 0;//used for int
//NEW DECLARATION FOR FLOAT
virtual void Push(const float&) = 0;//used for float
virtual const float& operator[](int index) = 0;//used for float
};
How can I avoid these redeclarations? I need sort of "virtual function templates", but this is not supported in C++.
Is my approach wrong?
Sorry for not highlighting the c++ syntax, this is my first post and I only managed to format it in code blocks. Thank you for your time!
EDIT #1 A BETTER SOLUTION(as suggested by jaggedSpire - many, many thanks)
I have modified IList
to
class IList {
public:
virtual IList& operator+( IList&) = 0;
virtual void afis() = 0;
virtual int g_Size() const = 0;
//templates
template<typename T>
void Push(const T& arg) //WORKS PERFECTLY
{
Queue<T>* cast = dynamic_cast<Queue<T>*>(this);
cast->Push(arg);
}
template<typename T>
const T& operator[](int index) //error
{
Queue<T>* cast = dynamic_cast<Queue<T>*>(this);
return cast->operator[](index);
}
};
and void C_Manager::testing()
to
class C_Manager{
public:
void testing()
{
IList * a = new CIntList(1);
a->Push(200);//WORKS PERFECTLY
int c = a->operator[](0); //ERROR
}
};
and it produces these errors
Error C2783 'const T &IList::operator [](int)': could not deduce template argument for 'T'
Error C2672 'IList::operator []': no matching overloaded function found
intellisense: no instance of function template "IList::operator[]" matches the argument list
Basically, it complains about every possibly templated function that has a T-related return type. How can I fix this to make my manager truly polymorphic?