I have written a program in C++ that compiles with clang++ but not with g++ and I would like to understand why.
The essential part is this:
class Table {
private:
...
std::unordered_map<std::string,Table> table_map;
...
};
I thought that std::unordered_map would be using pointers "under the hood", so that this is legal. I'm not declaring a Table inside of a Table, but I'm creating a container that has pointer(s) to Table(s) inside of a Table. Or so I thought. Clang++ has no problem with this and the program runs fine.
However, g++ complains about this, saying "note: forward declaration of 'class Table'
". This suggests I should explicitly make the std::unordered_map take a pointer (std::unordered_map<std::string,Table*>
, or perhaps some flavor of smart pointer). That requires I do some extra work (and I'm dealing with code I wrote over a year ago, so I'm not eager to have to figure out what I did in order to make the necessary changes).
Is this a bug in g++ or is clang++ doing something clever that's not really part of the standard? Is there a better way to rewrite this code so that it compiles on both clang++ and g++?
I have another class called Value, and there's a std::unordered_map of Values within Table, so would I get around this problem by creating a superclass Element from which Value and Table both inherit, and then having Table contain a std::unordered_map<std::string,Element>
? Or would such a map be unable to store Values and Tables because it was declared for Elements?