0

I have a transport listener that receives a json object. For this purposes different subscribers will be interested in different properties of the json msg. The problem with that means being able to handle the type of the property dynamically.

I was thinking of having a data structure similar to this to help:

std::unordered_map<std::string,std::vector<std::function<void (T)>>>; 
std::unordered_map<std::string,std::vector<T&>>>; 

//this doesn't work because I will be forced to have template T on a class template level, bound to the same type which is not what I want.

I was thinking of a union to encapsulate all possible types but that doesn't sound entirely feasible

How it will be used pseudocode:

void OnJsonObjectReceived(JsonObject msg)
{
   auto key = "test_prop";
   val = get_value_from_json_msg(key, msg) ;
   for(subscriber in _unordered_map.find(key)->subscribers)
   {
     subscriber = val;
   }
}
E_net4
  • 27,810
  • 13
  • 101
  • 139
Lews Therin
  • 10,907
  • 4
  • 48
  • 72
  • 1
    Have you considered a `variant` or a virtual hierarchy? – Zuodian Hu Mar 25 '20 at 01:46
  • @ZuodianHu I saw variant in my research but it can't handle vectors afaik? What's a virtual hierarchy? Will look it up – Lews Therin Mar 25 '20 at 01:47
  • 1
    You can put almost anything in a `variant`, including a `vector` or even another `variant`. What gave you the impression that you can't? – Zuodian Hu Mar 25 '20 at 01:50
  • A virtual hierarchy allows you to use instances of arbitrary child class types through a reference or pointer to a single base class type. – Zuodian Hu Mar 25 '20 at 01:54
  • @ZuodianHu I guess I misunderstood: https://stackoverflow.com/a/26208947 – Lews Therin Mar 25 '20 at 01:58
  • Ahh I see. That means you can't have `variant` or `variant`. `variant` is totally fine. – Zuodian Hu Mar 25 '20 at 02:03
  • @ZuodianHu Is variant possible? Don't you need to have a template type? As in can I have `variant, vector>` – Lews Therin Mar 25 '20 at 02:07
  • You're right. I was just too lazy to type the whole thing out. – Zuodian Hu Mar 25 '20 at 02:08
  • @ZuodianHu haha no worries. I will play with variant and see how that goes. Thanks man – Lews Therin Mar 25 '20 at 02:09
  • There are lots of JSON libraries for C++. [nlohmann/json](https://github.com/nlohmann/json), [RapidJSON](https://rapidjson.org/), and [JsonCpp](https://github.com/open-source-parsers/jsoncpp) are a few popular ones. Use one. – Miles Budnek Mar 25 '20 at 02:13
  • 2
    Note that simply "using variant" is not quite so simple because JSON is a recursive representation. You cannot express a variant whose element could be that variant itself. There needs to be some sort of indirection and type-erasure to make recursion possible. – eerorika Mar 25 '20 at 02:15
  • @MilesBudnek parsing the object is not the issue. Handling the notification to subscribers is the issue because of the different types the subscribers are interested in – Lews Therin Mar 25 '20 at 02:16
  • @eerorika Not sure I get you. A json object can't have a variant type. It's either a primitive or list of T. All I care about is passing jsonObject.Property to interested parties/subscribers – Lews Therin Mar 25 '20 at 02:17
  • 1
    @LewsTherin All of those libraries have some form of generic "JSON Value" object that you can pass to your subscribers. – Miles Budnek Mar 25 '20 at 02:18
  • @MilesBudnek Oh if that's true, it is exactly what I need! Thanks – Lews Therin Mar 25 '20 at 02:19
  • @LewsTherin A JSON object can have a JSON object as a property. If your narrow use case doesn't have need to consider that, then maybe the solution can be trivial. – eerorika Mar 25 '20 at 02:19
  • @eerorika You are right. I will have to think about it more. Thanks – Lews Therin Mar 25 '20 at 02:26
  • I think we may convert the json to protobuf, then we can play with protobuf objects which is easier to deal than json. https://stackoverflow.com/a/38441368/1292791 – prehistoricpenguin Mar 25 '20 at 03:05

0 Answers0