Workaround of insert different type object in one container?

Jul 1, 2015 at 1:55pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;

int main ()
{

  map<string, vector<float> > m_data; 
// insert some object into m_data:
  vector<float> m_mass{1.0,3.0,5.0,7.0};  // data is just an example.
  vector<float> m_velocity{1.0,3.0,5.0,7.0};
  m_data.insert(make_pair("mass",m_mass) );
  m_data.insert(make_pair("velocity",m_velocity) );

// a typical operation:
  map<string, vector<float> >::iterator iter=m_data.find("mass");
  if(iter!=m_data.end())
      iter->second.resize(2);
}


I used to use this “map<string, vector<float> > m_data" and insert some object like m_mass and m_velocity.

But now there is another one:
vector<unsigned int> m_charge{2,4,6,8};
The element of m_charge have to be unsigned int. But the operation to m_charge is the same with m_mass and m_velocity. If m_charge can be inserted into m_dat
a, this program gonna to be very brief; but it can't.

So I wander if there is anyway to put different type object in one container? Or is there other ways to attain my goal?

Thanks in advance for any help!
Last edited on Jul 1, 2015 at 2:00pm
Jul 1, 2015 at 2:07pm
Use a struct and put the different containers in there?
Jul 1, 2015 at 2:10pm
have to be unsigned int
Why? What happens if you store them in float (BTW why float? double is a native floating point type for most CPU)

Will this help: http://ideone.com/4W5hmF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <vector>
#include <map>
#include <string>

int main ()
{

	std::map<std::string, std::vector<float> > m_data;
	std::vector<float>        m_mass{1.0,3.0,5.0,7.0};
	std::vector<float>        m_velocity{1.0,3.0,5.0,7.0};
	std::vector<unsigned int> m_charge{2,4,6,8};
	m_data.insert(std::make_pair("mass",    m_mass) );
	m_data.insert(std::make_pair("velocity",m_velocity) );
	m_data.insert(std::make_pair("charge",  std::vector<float>(
	                           m_charge.begin(), m_charge.end())) );
	for(const auto p: m_data) {
		std::cout << p.first << ": ";
		for(const auto& n: p.second)
			std::cout << n << ' ';
		std::cout << '\n';
	}
}
charge: 2 4 6 8 
mass: 1 3 5 7 
velocity: 1 3 5 7 

Last edited on Jul 1, 2015 at 2:11pm
Jul 1, 2015 at 7:00pm
Do you really need the map at all? It seems to me that you could probably tell at compile time which vector you need and thus you can just use the variables directly.
Jul 2, 2015 at 2:36am
shadowmouse (237)
Use a struct and put the different containers in there?

To program above, it works. But there are two reasons compel me discard this solution:
1. At most time, data like "vector<float> m_mass" is used alone. So all subroutine of our program receive vector.
2. m_data.size() is usually larger than 20, but in fact only several vector like m_mass in it. So a struct will contain 20 variables but most of time only a few varibles exist.
Jul 2, 2015 at 2:53am
MiiNiPaa (7613)
have to be unsigned int
Why? What happens if you store them in float (BTW why float? double is a native floating point type for most CPU)

Maybe my example is not typical. In fact, m_data.size() is usually larger than 20. The type of data in m_data could be several types, such as unsigned int, float, int and user-defined type. Store data in float is because these data come from GPU, and for GPU float is usually a native type.
Jul 2, 2015 at 3:02am
dhayden (1415)
Do you really need the map at all? It seems to me that you could probably tell at compile time which vector you need and thus you can just use the variables directly.

Yes, this is what I do now. But m_data.size() is large, and I do the same thing than 20 times. It's not a hard work, but really boring. So that's why I wander if there is some smart tricks.
Jul 2, 2015 at 7:38am
Store data in float is because these data come from GPU, and for GPU float is usually a native type.
It was about 20 years ago. Now all FP units manipulates double precision numbers.

Also you can look into boost::any and boost::variant to be able to store anything in map.
Last edited on Jul 2, 2015 at 7:44am
Topic archived. No new replies allowed.