Прямое объявление структуры-члена

#c #class #struct

#c #класс #структура

Вопрос:

Я хочу написать такой код, но он не работает:

 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){}
};
  

Проблема в том, что я пытаюсь создать в синтаксическом анализаторе объект неполного типа. Если я поменяю местами реализации структур, проблема в том, что я пытаюсь получить доступ к структуре-члену неполного типа. Очевидно, что я могу решить эту проблему, сделав узел независимой структурой, но это кажется плохим, потому что я могу захотеть иметь в своей программе другие типы узлов.
Вопрос в том: могу ли я каким-то образом сделать прямое объявление структуры узла вне структуры синтаксического анализатора? Например:

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

Если это невозможно сделать, то каковы способы разрешения конфликта?

Комментарии:

1. Вы никогда не заявляли о пересылке node .

2. просто объявите функцию ast build_ast() в структуре и определите ее позже, после создания структуры ast.

3. Поместите объявление и определение классов в их соответствующие заголовки, а реализацию функций-членов — в .cpp файл, куда вы также должны включить соответствующие заголовки.

Ответ №1:

Вы должны отложить определение build_ast до ast получения полного типа:

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

inline здесь, чтобы сделать это объявление функционально идентичным тому, что у вас было в примере. Возможно, вы захотите удалить его и переместить build_ast в файл реализации

Вне определения структуры:

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

Для прямого объявления node вам нужно сделать это в parser определении. Другими словами, вы не можете перенаправить объявление внутреннего класса без определения внешнего.

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

Затем вы можете перейти к определению:

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