1
#ifndef TRIEAPI
#define TRIEAPI

#include <vector>
#include <string>
#include <unordered_map>

using namespace std;

typedef struct NodeStruct
{
    bool validNgram = false;
    unordered_map<string, struct NodeStruct> children;
    struct NodeStruct* parent;
    string nodeWord;

    NodeStruct(struct NodeStruct* par, string w) : parent(par), nodeWord(w) {} //constructor (yeah, structs have them too)
    NodeStruct() {}
}Node;


void addNgramTrie(Node* root, string ngram);
void findNgramsTrie(Node* root, string query);
void splitText(string query, vector<string> &words);
void deleteNgramTrie(Node* root, string ngram);
void recursiveParentDeletion(Node* node, Node *root);


#endif // TRIEAPI

When I try compiling the program I get an error on this header file about the pair.h (compiling in g++ 5.4 c++11):

trie.h:14:46:   required from here
/usr/include/c++/5/bits/stl_pair.h:102:11: error: ‘std::pair<_T1, _T2>::second’ has incomplete type
       _T2 second;                /// @c second is a copy of the second object
           ^
In file included from trie.cpp:10:0:
trie.h:11:16: note: forward declaration of ‘struct NodeStruct’
 typedef struct NodeStruct

I don't understand where I am wrong.

JimS
  • 349
  • 1
  • 4
  • 19
  • @JimS, those `typedef`s are useless in C++, and just adds clutter to the code. You don't need the "Eloborated type specifier" – WhiZTiM Mar 07 '17 at 01:00
  • Perhaps [c++ - How to have an unordered_map where the value type is the class it's in? - Stack Overflow](https://stackoverflow.com/questions/13089388/how-to-have-an-unordered-map-where-the-value-type-is-the-class-its-in) is a much better duplicate. cc @BaummitAugen (although it was 4 years ago) – user202729 Mar 06 '21 at 16:21
  • @user202729 Added, good catch – Baum mit Augen Mar 06 '21 at 21:39

1 Answers1

1
typedef struct NodeStruct
{
    bool validNgram = false;
    unordered_map<string, struct NodeStruct> children;

This can't possibly work. Imagine if, for example, the size of an unordered_map depended on the size of the types it contained. That's certainly possible. So, to know the size of an unordered_map<string, struct NodeStruct>, you'd first need to know the size of a struct NodeStruct. But since a struct NodeStruct contains such an unordered_map, you also need to know the size of the map to know the size of the struct.

How can that possibly work? Maybe use unique_ptr<struct NodeStruct> in the map?

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • But why when I used a map instead of an unordered one I didn't get this error? – JimS Mar 07 '17 at 01:00
  • @JimS Language level answer: You got lucky, it need not work with `std::map`. – Baum mit Augen Mar 07 '17 at 01:10
  • 1
    @JimS When you break the rules, the rules get broken. Follow the rules and the system will too. (My argument shows that it can't work in general, not that there can't be specific cases where it might happen to work. My argument shows that you should not expect it to work.) – David Schwartz Mar 07 '17 at 01:38
  • The container uses dynamic allocation to allocate space for its contents, so there's no logical problem with a struct having a container of itself. It's just that the standard standard library containers aren't required to support it. You can certainly get other container implementations that do support it. – M.M Mar 06 '21 at 21:55