I was just messing around over at ideone.com when I figured this out, with a little help from @Luc-Danton and @DeadMG from the Lounge C++ (thanks guys). So here’s the source code for a minimal linked list in C++.
/** Linked Lists in C++
** @author Muhammad Ahmad Tirmazi
**/
#include <string>
#include <iostream>
#include <vector>
#include <typeinfo>
using namespace std;
struct element
{
element(void* obj, std::type_info const* t): object(obj), type(t) {}
void* object;
std::type_info const* type;
};
class linked_list
{
std::vector< element* > stack;
public:
linked_list() {}
virtual ~linked_list() {}
template<typename T> void add_element(T* obj)
{
void* v_obj = static_cast< void* >( obj );
stack.push_back( new element( v_obj, &typeid(obj) ) );
}
template < typename T > T* get_element( int index )
{
if ( *stack[index]->type == typeid(T*) )
{
return static_cast<T*>( stack[index]->object );
}
else throw 1;
}
};
int main()
{
linked_list list;
int i = 5;
cout << i << endl;
list.add_element( &i );
list.add_element( new string("Hello!") );
try{
int* j = list.get_element<int>(0);
cout << *j << endl;
cout << *list.get_element<string>(1) << endl;
} catch(...){ cout << "ERROR!" << endl; }
}
As you can see, I use C++’s standard RTTI to evaluate and compare the type’s of the elements. There’s an element struct for holding the values and type information. I should have used boost::any instead of void*, but I’m too lazy rewrite the code now
.
Also, @LucDanton created a better version in less code ( I’m horrible
) :
#include <string>
#include <iostream>
// needed for any_vector:
#include <vector>
#include <typeinfo>
#include <tuple>
#include <stdexcept>
class any_vector {
public:
struct bad_element_access: public virtual std::exception {};
template<typename T>
void
push(T& obj)
{
stack.push_back(std::make_tuple(&obj, &typeid(obj)));
}
template <typename T>
T&
get(int index)
{
using std::get;
if(*std::get<1>(stack[index]) == typeid(T)) {
return *static_cast<T*>(get<0>(stack[index]));
} else {
throw bad_element_access();
}
}
private:
typedef std::tuple<void*, std::type_info const*> any_type;
std::vector<any_type> stack;
};
int main()
{
any_vector any;
int i = 5;
std::cout << i << '\n';
any.push(i);
try{
int& j = any.get<int>(0);
std::cout << j << '\n';
} catch(...) {
std::cerr << "ERROR!" << '\n';
}
}