Home > Software engineering >  How can I make a C typename nest itself and "infinitely" recurse?
How can I make a C typename nest itself and "infinitely" recurse?

Time:04-21

Im trying to turn this piece of JSON into a C type using a neat little JSON parsing library I have created.

[
 "a",
   [
      "b",
      [
         "c",
         [  
            "d", 
            ["... so on so forth"] 
         ]
      ]
   ]
]

Currently, this is technically what the type would look like in C , however this is obviously invalid as the typename cannot reference itself:

typename std::variant<std::string, std::vector<requirements_type>> requirements_type;

Is there any way to make an infinitely recurring typename that can handle this sort of structure?

CodePudding user response:

As mentioned in comments, you cannot have an infinetely nested type like your requirements_type. The size of objects of a type is finite. Also in practice your JSON will not be infintely nested. You need to stop the nesting somewhere.

A type alias cannot refer to itself, but you can refer to the class while declaring its members:

struct requirements_type {
    std::variant< std::string, std::vector< requirements_type > > data;
};

CodePudding user response:

As mentioned in 463035818_is_not_a_number's answer

Instead of using a typename I can use a class that references itself:

struct RequirementArray {
    std::variant<std::string, std::vector<RequirementArray>> self;
};

I can recurse through this by using this simple method:

void recurseAndOutput(RequirementArray array, int i) {
  try {
    std::vector<RequirementArray> requirementArrays = std::get<std::vector<RequirementArray>>(array.self);
    for (RequirementArray requirementArray: requirementArrays) {
      recurseAndOutput(requirementArray, i   1);
    }
  } catch (std::bad_variant_access const & ignored) {
    std::string string = std::get<std::string>(array.self);
    printf("%s - %i", string.c_str(), i);
  }
}
  • Related