mercredi 20 novembre 2019

How to sort out forward references for a tree data structure in C++

In C++11, I want to define a tree data structure in which each node has a set of keys (std::string), and each key is associated with two values: another std::string, and a pointer to a child node in the tree. The natural way to do this seemed to be to make a node be a std::unordered_map, with std::string keys and with values that are a std::pair of std::string and the pointer to the child node. At present, I have this:

struct tree_node;

typedef std::pair<std::string, tree_node *> tree_value;

struct tree_node {
    std::unordered_map<std::string, tree_value> key_val_map;
};

The annoying thing is the struct in the middle of all this; when I'm working with these data structures I'm constantly having to make an extra step through key_val_map. I'd like tree_node to simply be typedefed as the std::unordered_map in question. It seems like this should be possible, since tree_value only refers to tree_node by pointer; I should be able to somehow forward-declare tree_node so that I can define tree_value. I can't find a way to do so, though.

One attempt was to typedef tree_node in a single line by itself:

typedef std::unordered_map<std::string, std::pair<std::string, tree_node *>> tree_node;

But that gives the error "Expected a type" when it hits the tree_node * in the declaration; the typedef has not yet happened, so the compiler doesn't know what a tree_node is. Fair enough. I also attempted to just vaguely forward-declare tree_node, since it seems to me that the compiler should not need to have complete information about it when I only refer to it by pointer:

class tree_node;

typedef std::pair<std::string, tree_node *> tree_value;

typedef std::unordered_map<std::string, tree_value> tree_node;

But this gives the error "Typedef redefinition with different types", on the final line.

Surely there is a way to sort out this can of worms. If I can make it work when tree_node wraps the unordered_map inside a struct, why can't I make it work when I just get rid of that pointless one-member struct? I basically just want to make that struct "transparent" – I don't want to have to keep referring to key_val_map in my code. Is there a way?

Aucun commentaire:

Enregistrer un commentaire