Использовать указатель на функцию-член класса перед определением класса C

#c #class #typedef

#c #класс #typedef

Вопрос:

У меня есть следующий код:

 // FILE_NAME: compiler.h

typedef enum Precedence { /* ENUM MEMBERS */ } Precedence;
typedef enum TokenType { /* ENUM MEMBERS */ } TokenType;

typedef void (Compiler::*ParseFn)();

typedef struct ParseRule {
    ParseFn prefix;
    ParseFn infix;
    Precedence precedence;
} ParseRule;

class Compiler {
    public:
        std::unordered_map<TokenType, ParseRule> rules;
        ParseRule getRule(TokenType type) {
            return rules[type];
        };
        void binary();
        void unary();
};
 

Я пытаюсь определить хэш-карту, которая сопоставляет ключ TokenType со значением, имеющим форму структуры ParserRule .

Пример пары ключ-значение для Compiler::rules hashmap выглядит следующим образом:

 rules[TOKEN_MINUS] = {unary, binary, PREC_TERM}
 

Когда я пытаюсь скомпилировать с C 11, я получаю следующую ошибку, а также многие другие:

 ./compiler/compiler.h:58:15: error: use of undeclared identifier 'Compiler'
typedef void (Compiler::*ParseFn)();
 

Это имеет смысл, поскольку я пытаюсь использовать класс Compiler для определения типа ParseFn до определения Compiler класса.

Я очень новичок в программировании на C / C (я начал изучать пару недель назад), поэтому мне было интересно, есть ли другой способ определения типов и классов, не вызывая ошибки компилятора.

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

1. Это не решает вопрос, но в C вам не нужно typedef enum Precedence { ... } Precedence; танцевать. Это C вещь. В C enum Precedence { ... }; этого достаточно.

Ответ №1:

Вам необходимо (предварительно) объявить Compiler как класс, прежде чем ссылаться на него:

 class Compiler;

typedef void (Compiler::*ParseFn)();
 

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

1. Это сработало, большое вам спасибо! Я думал об этом много раз, но мне просто казалось, что я объявляю класс дважды, что, как я предполагал, приведет к ошибке.

2. Вы можете объявлять вещи столько раз, сколько захотите, если объявления совпадают. Вы можете определить их только один раз.