Best/Fast structure for variable "variable"

Hi, i am new to this forum. I read a lot but this is my first post.


I need an universal variable which can hold long,double,std::string, double[3] most of the time. Very seldom i need also a vector<vector<string>> like a little table with strings in the variable. These variables should be put in a map to access them via string key´s like std::map<string, variable>...

Sure, i would encapsulate all the stuff but i am worry about how to make the best choice for the internal structure.

One way would be the "OOP" way. I make a baseclass and for each typ an inherit class with the specialities for this object. I have heard that RTTI -typecasting is timeconsuming.

The next one will be, i always use a string for the long,double,string and convert the string on demand.

There may be a lot of more way´s ??

First goal should be the access speed and second the memory footprint for this stuff.

Have you got any tips/hints advice how you would choice about this ?

Thanks in advance,

Howie
I have to use std::string for strings. These are dynamicly so i don´t know how union works with this. As i know (i have used unions 15 years back) the share the same memory as the biggest varable is. But not dynamicly.

Howie
I know theoreticly a little bit about "any" from boost. But i don´t know how fast it is compared to the classic oop approach.

Howie
This is an example:

#include <map>
#include <boost/any.hpp>

using boost::any_cast;
typedef std::map<std::string, boost::any> t_map;

int main(int argc, char **argv)
{

t_map map;
char *pc = "boo!";

map["a"] = 2.1;
map["b"] = pc;

cout << "map contents" << endl;
cout << any_cast<double>(map["a"]) << endl;
cout << any_cast<char*>(map["b"]) << endl;

return 0;
}


But i have also to deal to much with the datatypes. In a classical way i have a kind of class_type etc.

Howie
I don't want to depreciate Howie's approach. As for my a don't know boost::any. But recently i had to implement something like that. I used void* to hold anything in the same class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
struct TreeNode
{
	TreeNode* m_parent;
	TreeNode* m_left;
	TreeNode* m_right;

	node_t m_type; //there's enum node_t{UNKNOWNNODE, STRING, DOUBLE, FUNCTION1};
	void* m_content; //pointer to ANY data

	TreeNode()
	{
		m_content = (void*)0;
		m_type = UNKNOWNNODE; 
		m_parent = m_left = m_right = 0;
	}

	TreeNode(double number)
	{
		m_type = NUMBER;
		m_content = new double(number);
		m_parent = m_left = m_right = 0;
	}
	TreeNode(fn1 func) //there's typedef double (*fn1)(double);
	{
		m_type = FUNCTION1;
		m_content = func;
		m_parent = m_left = m_right = 0;
	}

	TreeNode(string id)
	{
		m_type = STRING;
		m_content = new string(id);
		m_parent = m_left = m_right = 0;
	}


	~TreeNode()
	{
		switch(m_type)
		{
		case STRING: delete (string*)m_content; break;
		case NUMBER:   delete (double*)m_content; break;
		case FUNCTION1:    break; //no need to delete function
		}
		delete m_left; delete m_right;  //destroy subtree recursively
	}
@melkiy
Reads interesting. Probably "the" universal aproach. I will think of it.

Thanks,

Howie
Well void* isn't universally compatible.

Acutally, I should leave it at: void* is not typesafe.

I would consider using a type erasure approach. That will necessarily incur virtual function calls to access
the contained data, however.

(Note that boost::any is implemented using type erasure).
Last edited on
Topic archived. No new replies allowed.