1

I'm trying to do this in C++:

struct sagrup
{
    int imps;
    int clicks;
    int uclicks;
    int conversions;
    int * variable;
    unordered_map<int, struct sagrup> siguiente;
};

unordered_map<int, struct sagrup> agrupacion;

And I'm getting error: forward declaration of ‘struct sagrup’

I want to have that struct and add other struct into that ordered map so it will be like a tree.

Thanks to anyone that could help!

Aycan Yaşıt
  • 2,106
  • 4
  • 34
  • 40
Yind
  • 335
  • 3
  • 17

2 Answers2

3

You have a couple issues:

First, you do not need to use struct everywhere. Second, are attempting to use an incomplete type with a template that requires a complete type definition (otherwise it doesn't know how to construct it). That map should be declared as a pointer, not another instance of sagrup.

The resulting code looks like this:

struct sagrup
{
    int imps;
    int clicks;
    int uclicks;
    int conversions;
    int * variable;
    unordered_map<int, sagrup*> siguiente;
};

unordered_map<int, sagrup> agrupacion;
Zac Howland
  • 15,777
  • 1
  • 26
  • 42
  • There's not necessarily a never-ending construction chain here -- `unordered_map` doesn't have to have a member of type `V` in it. – Adam Rosenfield Jan 08 '14 at 18:36
  • @AdamRosenfield That verbiage was fixed. – Zac Howland Jan 08 '14 at 18:37
  • The sentence "Second, you have a never ending construction chain with your siguiente member" is not necessarily true, depending on how `unordered_map` is implemented. `std::shared_ptr` can be instantiated just fine, even though `sagrup` is an incomplete type. There's no infinite construction chain in `struct X { shared_ptr p; };` because a `shared_ptr` doesn't have a member of type `X`, it has a member of type `X*`, so the construction of a `shared_ptr` doesn't need to construct an `X`. – Adam Rosenfield Jan 08 '14 at 18:42
  • @AdamRosenfield Sorry, missed one of the sentences in my first edit. Fixed. Though, examples of `shared_ptr` do not apply to the OP's current problem. – Zac Howland Jan 08 '14 at 18:44
  • Thank you!, using sagrup* fixed the problem. =) Thanks – Yind Jan 08 '14 at 18:47
1

Before the type has been fully defined, the compiler does not know anything about the type; i.e. what members are and their sizes and its in complete

Forward declaration is used only for references and pointers to such a struct.

Alternatively you can use:

unordered_map<int, sagrup*> siguiente;

inside your struct

P0W
  • 46,614
  • 9
  • 72
  • 119
  • Forward declarations can also be used for template parameters, *only if the class allows it*. For example, `std::shared_ptr<>` can be instantiated on an incomplete type, because the standard explicitly allows that. But `std::unordered_map<>` cannot be. – Adam Rosenfield Jan 08 '14 at 18:39
  • @AdamRosenfield `shared_ptr` and `unique_ptr` can use incomplete types because they don't really care about the type, but rather a pointer to the type. – Zac Howland Jan 08 '14 at 18:43
  • @ZacHowland: Right, that's why whether or not a template can be instantiated on an incomplete type depends on the particulars of the class's implementation. `shared_ptr<>` can be, `unordered_map<>` can't. – Adam Rosenfield Jan 08 '14 at 18:46