Aleksandr Tukallo Aleksandr Tukallo - 1 month ago 12
C++ Question

Forward declaration of member struct

I want to write such a code, but it doesn't work:

struct ast;
struct parser;

struct parser
{
struct node
{
node *parent;
};

ast build_ast() //here we want to use object of ast tyoe
{
node *ret = new node;
return ast(ret);
}
};

struct ast
{
parser::node *root; //here we try to access member struct of y
ast(parser::node *rt):root(rt){}
};


The problem is that I try to create in parser an object of incomplete type. If I swap implementations of structures, the problem is that I try to access member struct of incomplete type. Obviously, I can solve this problem, by making node an independent structure, but that seems bad, because I may want to have other node types in my program.
The question is: can I somehow make a forward declaration of node struct outside the parser struct? For example:

struct ast;
struct parser;
struct parser::node; //making a forward declaration of member struct


If this cannot be done, what are the ways to solve the conflict?

Answer

You have to defer the definition of build_ast until ast is a complete type:

inline ast build_ast(); //here we want to use object of ast type

inline is here to make this declaration functionally identical to what you had in example. You may want to remove it and move build_ast to an implementation file

Outside of the struct definition:

ast parser::build_ast()
{
    node *ret = new node;
    return ast(ret);
}

To forward-declare node, you need to do this within parser definition. In other words, you cannot forward-declare an inner class without defining the outer.

struct parser
{
    struct node;
    // ...
};

You can then proceed with a definition:

struct parser::node
{
    node *parent;
};