pouët.net

Easy lookup/access to members in "an array" of different datatypes if possible

category: code [glöplog]
But as a former question it would be if its possible to store members of different datatypes in an array without much painstaking work.

As an example of this consider calling a function looking like this:

Code:pointer->Add<char>(150); pointer->Add<int>(12000);

etc...

The Add function in the class is defined like this:

Code:template <class T> void Add(T value) { table.push_back(new Table<T>(value)); }


data is:

Code:std::vector <TableBase *> table;


TableBase is nothing more than a class with nothing like maybe just a virtual or pure virtual function.
Table is a template class derived TableBase

How can I get the fucking data from the table as the datatype since ive added it in the template function. is it possible with decltype, auto or some casting. im out after simplest design for template to access data in an array. im not sure how such array would work. ideas, directions are welcome.
added on the 2012-02-12 14:39:48 by rudi rudi
you could use a class that serializes datatypes into binary stream, such aas qdatastream.
added on the 2012-02-12 14:47:31 by Navis Navis
Wrong programming language. Or wrong usage of chosen programming language.

Quote:
But as a former question it would be if its possible to store members of different datatypes in an array without much painstaking work.


No, not in C++.

You could try stuff from Boost, such as Boost.Any, though. There, somebody else did the painstaking work for you.
added on the 2012-02-12 14:47:44 by Moerder Moerder
well if you consider void* as typeless pointer sure you can do it.
but in your case you have to define a set of overload functions for each type you want.
like
int Get();
char Get();
...
and in each return you enforce a type case for that value.
added on the 2012-02-12 14:52:50 by panic panic
type cast*
added on the 2012-02-12 14:53:53 by panic panic
Use the Boost thing or something similar. Or even better: figure out why it is you want this, take a few steps back and devise a different/simpler approach that better befits language.
added on the 2012-02-12 15:00:22 by superplek superplek
Sounds like one of those cases where OO nazis would tell you your design is flawed. Methods that work on a Table object should be encapsulated in the Table class, with a common interface defined in TableBase by virtual methods. Then you don't need to know what specific kind of TableBase pointer you're pulling out of the "table" vector. Polymorphism.

If you're happy with your design, though, you should look at typeid and dynamic_cast: RTTI. One gives you run-time type information, the other lets you cast a pointer safely, returning NULL if you're trying to cast to an incompatible type.
added on the 2012-02-12 15:22:57 by doomdoom doomdoom
doomdoom: i think its something like this i am out after
added on the 2012-02-12 15:36:22 by rudi rudi
and i dont understand what Navis said
added on the 2012-02-12 15:37:19 by rudi rudi
check how qdatastream (from qt) works. Type it in google. Then have a look at the >> << operators.

added on the 2012-02-12 15:42:33 by Navis Navis
Navis: i see. but, i dont like using external libs for this. i hoped i would not mix it with my code.
added on the 2012-02-12 15:51:39 by rudi rudi
what doom said.
added on the 2012-02-12 16:26:25 by raer raer
If it's performance you're looking for, really think twice before using RTTI. Really think twice before using it in any case, as, conceptually, it's really just red tape.
added on the 2012-02-12 16:57:40 by superplek superplek
In my experience, whenever you consider using RTTI, your code-design is flawed.
added on the 2012-02-12 17:39:23 by kusma kusma
Amen.
added on the 2012-02-12 17:45:46 by superplek superplek
"aw hell, it's just a temporary solution!.." :D
added on the 2012-02-12 17:55:52 by kbi kbi
You're all crazy folk, what with your "Disable RTTI and exception handling" checkboxes checked and whatnot!
added on the 2012-02-12 21:45:03 by sagacity sagacity
switch language to ruby, and plan ahead for the perfomance hit ;)
added on the 2012-02-12 21:57:40 by n0der n0der
ruby+performance = false
added on the 2012-02-13 05:37:45 by panic panic
I've had a similar problem, and came up with the following solution:
Instead of having one single array with all elements, I came up with a struct:

Code: struct MyData { enum DataType { Float, Vector, Whatever, //... } struct DataEntry { DataType dataType; int index; } DataEntry* data; float* floatData; vector* vectorData; whatever* whateverData; //... } //... MyData myData; for (int i = /*iterate over everything in myData*/) { switch(myData.data[i].dataType) { case MyData::DataType::Float: float value = myData.floatData[myData.data[i].index]; //... break; case MyData::DataType::Vector: vector value = myData.vectorData[myData.data[i].index]; //... break; case MyData::DataType::Whatever: //... break; } }


I know, it looks ugly, but it serves its purpose. You have a "collection" where every element has a different (known!) type.
added on the 2012-02-13 13:15:24 by xTr1m xTr1m
xTr1m: Use a union, like:
Code:struct DataEntry { union { float f; vector v; whatever w; } value; DataType type; }

You could also rely on RTTI as previously suggested.
added on the 2012-02-13 13:45:53 by Tjoppen Tjoppen
xTrim: I'm using something similar for variant implementation, but instead of storing a heck-a-load of separate variables like in your case, I just go with a void* that contains pointer to variable of described type. Saves a few bytes, especially if you use a lot of variants (as is in my case, where variants define curve segment/curve node values)
added on the 2012-02-13 14:08:11 by kbi kbi
haha Tjoppen, right, was just about to say :) people, read your books before coding okay?

kbi: that level of indirection, even if the memory pointed to is magically allocated in a cachefriendly manner, kills babies in their sleep. union the voidptr with atomic types and only use it for bigger objects.
added on the 2012-02-13 14:23:00 by superplek superplek
(i.e. at least try not to point to stuff thats equal/smaller size than the pointer itself)
added on the 2012-02-13 14:28:48 by superplek superplek
xTr1m: looks like a waste of C++. Why not Zoidberg:

Code:class MyData { public: virtual void process(); } class MyData_int : public MyData { public: int value; void process() { //... } } class MyData_float : public MyData { public: float value; void process() { //... } } //... MyData *myDataArray[100]; //... for (int i = 0; i < 100; ++i) myDataArray[i]->process();


It's more compact, maintainable and flexible, and it's less error-prone. Problems like this are precisely why C++ supports polymorphism.
added on the 2012-02-13 15:54:12 by doomdoom doomdoom

login