How can I solve the following circular dependency?
typedef boost::variant<int, bool, double, std::string, Structure> Value;
typedef std::list<std::pair<std::string, ValueContainer>> Structure;
typedef std::vector<Value> ValueContainer;
I’m attempting to represent objects from a C api database library in a more C++ form. This database allows one to store values or arrays of values, as well as having a representation for Structures, as follows:
typedef struct ApiStructureMember
{
char* name;
struct ApiValueContainer value;
struct ApiStructureMember_T* next;
} ApiStructureMember_T;
Finally, a union is used to represent a value, as follows:
typedef struct ApiValue
{
union
{
int i;
const char* s;
...
struct ApiStructureMember_T* firstStructureMember;
} value;
} ApiValue_T;
You can’t have types mutually containing each other. Think about it: the compiler would get into an infinite loop generating the data.
There are two general patterns: the first is through data types pointing to each other
If you leave away the pointers, and implement the Even and Odd nodes with containment by value, then the compiler can never resolve the definitions.
In general: just draw a picture of how you want to lay out the data, with boxes representing data and lines connecting the various parts. Then replace each box with a class, and each line with a pointer to the corresponding class. If you have a circular dependency somewhere, simply forward declare the classes at the top of your code.
The second circular dependency is through the Curiously Recurring Template Parameter (CRTP)
Your example would be using the CRTP with
StructureasXandstd::list< ..., Structure>asY<X>.