2

I have data represented as follows:

enter image description here

I need to make this data accessible in my C++ application. I also need to be able to access items associatively via variable key names; for example:

std::string key = "ema50";
double value = data[key];

A std::vector<std::map<std::string, double>> would be great for this, except I'm not sure what to do about the groups item. I'd like to be able access the testing or validation arrays for a given item in the vector:

int testingGroups[9] = data["groups"]["testing"];
int validationGroups[9] = data["groups"]["validation"];

Is there a way I can accomplish this? I'm do prefer to use vectors and maps, but I'm open to other solutions so long as I can access data items associatively.

Would using templates like described here be the way to go?

Community
  • 1
  • 1
Chad Johnson
  • 21,215
  • 34
  • 109
  • 207
  • you could use tuples. See if this fits your needs [tuples class msdn](https://msdn.microsoft.com/pt-br/library/bb982837.aspx). – Carafini Apr 15 '16 at 23:14
  • Is speed critical? I mean you could store these values as strings and the caller could specify what to convert to when accessing the data like: `data.get(key);`. – Galik Apr 15 '16 at 23:15
  • Possible duplicate of : https://stackoverflow.com/questions/25988288/is-there-an-elegant-way-to-represent-a-map-containing-different-types-in-c – Galik Apr 15 '16 at 23:18
  • Speed is going to be pretty important, but if nothing else surfaces, I'll give your suggestion a try, @Galik. – Chad Johnson Apr 15 '16 at 23:19
  • Would it be OK to use notation like `data.item( "ema50" )`? If the result type can't be specified then you're into variant-land. – Cheers and hth. - Alf Apr 16 '16 at 00:17
  • I think that would be a form of casting? That's probably going to be slow. – Chad Johnson Apr 16 '16 at 00:56
  • No, that's not a form of casting, and it's what you need for any reasonable performance. Converting values from strings, or using variants, is not reasonable performance. – Cheers and hth. - Alf Apr 16 '16 at 01:20

1 Answers1

3

The accepted answer in the link you provided, C++ std::map holding ANY type of value , is actually the way to go. Essentially you want a map of VARIANTs - objects that can be of any value, even another map (which gives you the ability to have multiple indices, just not as pretty - e.g. it would be something like data["foo"].asMap["bar"]). Variants are generally fancy unions with a hint member, e.g.

struct MyVariant {
    int type; // or enum
    union {
        int asInt;
        bool asBool;
        double asDouble;
        // etc...
        std::map<std::string, MyVariant> asMap;
    }
};        

but as in the accepted answer to the referenced question, you have to be able to intelligently handle pointer types that you union with other types. You can add a 'flags' member to denote ownership of the memory (deep copy) as opposed to a pointer to memory not owned by the variant (shallow copy). And - one of the unionized types can be another map that will allow you to create an arbitrarily deep structure.

Community
  • 1
  • 1
JackLThornton
  • 375
  • 3
  • 14