I'm designing a simple Array
class with the capability of holding any type of object, like a vector that can hold multiple types of data in one object. (This is for learning purposes.)
I have an empty base class called Container
:
class Container {};
And a templatized subclass called Object
:
template <class T>
class Object : public Container {
T& object;
public:
Object(T& obj = nullptr) : object(obj) {}
};
I have an Array
class which holds a vector
of pointers to Container
s which I use to hold Object
s:
class Array {
std::vector<Container *> vec;
public:
template <class T>
void add_element(const T&);
auto get_element(int);
};
add_element
stores elements into Object
s and puts them into vec
:
template <class T>
void Array::add_element(const T& element)
{
vec.push_back(new Object<T>(element));
}
get_element
removes the element from it's Object
and passes it back to the caller. This is where my problem lies. In order to remove the element from the Object
, I need to know what type of Object
it is:
auto Array::get_element(int i)
{
return (Object</* ??? */> *)vec[i])->object;
}
Is there some way for me to find out what sort of object I'm storing?
Edit: since people are claiming that this is not possible, how about this. Is there some way of actually storing type information inside of a class? (I know you can do that in ruby). If I could do that, I could store the return type of get_element
in each Object
.
All the template parameters are fixed+known at compile-time. If there are compiler errors due to template instantiation, they must be caught at compile-time!
A class template must be declared before any instantiation of a corresponding template class. A class template definition can only appear once in any single translation unit. A class template must be defined before any use of a template class that requires the size of the class or refers to members of the class.
C++ template is also known as generic functions or classes which is a very powerful feature in C++. A keyword “template” in c++ is used for the template's syntax and angled bracket in a parameter (t), which defines the data type variable.
1. What is the syntax of class template? Explanation: Syntax involves template keyword followed by list of parameters in angular brackets and then class declaration.
I was thinking something along the lines of this template for your get_element
.
template <class T>
T& Array::get_element(int i, T &t)
{
Object<T> *o = dynamic_cast<Object<T> *>(vec[i]);
if (o == 0) throw std::invalid_argument;
return t = o->object;
}
Array arr;
double f;
int c;
arr.get_element(0, f);
arr.get_element(1, c);
But alternatively, you could use this:
template <class T>
T& Array::get_element(int i)
{
Object<T> *o = dynamic_cast<Object<T> *>(vec[i]);
if (o == 0) throw std::invalid_argument;
return o->object;
}
f = arr.get_element<double>(0);
c = arr.get_element<int>(1);
The return type of a function like Array::get_element
must be determined at compile time. Since class Array
does not know what types of containers it stores at compile time, the only option is to just return the base Container*
pointer. Then users of that code can use virtual functions and/or dynamic_cast
to deal with those generalized containers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With