Hello, this is a newbie question, sorry for that,
I am trying to port some Java code to C++. In this code I have a hashmap connecting string values to float arrays of varying sizes. They are specified like this:

HashMap <String, float[]> hm = new HashMap <String, float[]> ();

hm.put("C", new float[] {
	3, 0, 0 ,  1, 0, 1 ,  0, 1, 1 , 0, 5, 1 ,  1, 6, 1 ,  3, 6, 1 
 }
 );
hm.put("D", new float[] {
     0, 0, 0 ,  2, 0, 1 ,  3, 1, 1 ,  3, 5, 1 ,  2, 6, 1 ,  0, 6, 1 ,
	 0, 0, 1 
 }
 );

... and so on.

I can see there are lots of strategies for storing dynamic arrays and key to value lookups, but my problem is this: How do I define all these values in a similarly nice way without making some totally unwieldy frankenstein code? The only way I can see is to make a constant for each float array I want to store. Each of these would have to have a unique single variable name, which already negates the whole point of using arrays and containers! Any ideas would be appreciated.

Recommended Answers

All 4 Replies

Using boost would make it easier for you, for example :

#include <iostream>
#include <string>
#include <map>
#include "boost/shared_array.hpp"
using namespace std;

typedef boost::shared_array<float> Array;
typedef std::pair<string,Array> MapElement;
typedef std::map<string,Array> Map;

MapElement makeElement(const string& str,float* data){
	return MapElement(str, Array(data));
}

int main(){

	Map m = Map();
	float data1[] = {1,2,3,4,5,6,7,8,9,0};
	float data2[] = {65,23,232,545,123,0,-2343};
	m.insert( makeElement("i",data1) );
	m.insert( makeElement("j",data2) );

}

Or you can use just stl's std::vector instead of pointers like so:

#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;

typedef std::map<string,std::vector<float> > Map;
typedef std::pair<string,std::vector<float> > MapElement;

template<size_t SIZE>
MapElement makeElement(const std::string& str, float (&ptr)[SIZE]){
	return MapElement(str,std::vector<float>(ptr,ptr+SIZE));
}
template<class ForwardIterator>
void print(ForwardIterator& begin, ForwardIterator& end){
	while(begin != end){
		cout << *begin++ << " ";
	}
}
int main(){
	float data1[] = {1,2,3};
	float data2[] = {4,5,6,7,3};
	Map m = Map();
	m.insert( makeElement("i",data1) );
	m.insert( makeElement("j",data2) );
	Map::const_iterator itr = m.begin();
	while(itr != m.end()){
		cout << itr->first << " ";
		print(itr->second.begin(),itr->second.end());
		cout << endl;
		++itr;
	}
}

Hi firstPerson, thanks for your reply, that's helpful! However, that's my point exactly - in my hashmaps, there might be 60 or 70 entries. I only put two in the example code to avoid posting several hundred lines for a simple query. Is there any alternative to first making a unique single variable name for each entry? i.e. data1[], data2[], etc. And what happens to the memory when it is done this way, is the allocation double what it should be?

I don't think there is a way around this with C++, in C++0X array initializer comes close. But in C++ you will have to something similar as shown above. You can control the scope of data for example like so :

void initialize(Map& map){
  data1 ...
  data2 ..
}

and so that way you control the memory a little bit more.
Alternatively you can use a file to initialize the map by loading the data into a vector and using the second approach.

OK then, I will do it this way if I have to - the idea of loading from a file is probably best, thanks for the tips!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.