std :: вариант с предварительным объявлением - PullRequest
1 голос
/ 07 февраля 2020

Я работаю на простом автомате, похожем на this .

Я пытаюсь кодировать свои состояния в отдельных классах, которые выглядят следующим образом:

// class StateA; (1)
// class StateB; (2)

using State = std::variant<StateA, StateB>;

class StateA {
  State handle(/* some params */) { return StateB(); };
};

class StateB {
  State handle(/* some params */){ return StateA(); };
};

Теперь мой вариант ничего не знает о StateA и StateB, что приводит к use of undeclared identifier 'StateA'. Если я раскомментирую (1) и (2) и получу предварительное объявление, я получу incomplete type 'StateA' used in type trait expression

Есть ли способ получить вариант с классами, в котором есть вариант?

Ответы [ 2 ]

2 голосов
/ 07 февраля 2020

Вы должны убедиться, что оба ваших члена variant являются полными типами в той точке, где вы их используете, например, перемещая определения для handle методов за пределы ваших классов:

#include <variant>

class StateA;
class StateB;

using State = std::variant<StateA, StateB>;

class StateA {
    State handle(/* some params */);
};

class StateB {
    State handle(/* some params */);
};

State StateA::handle() { return StateB(); }

State StateB::handle() { return StateA(); }
0 голосов
/ 07 февраля 2020

Возможно, вы можете использовать динамический c полиморфизм в качестве более удобного проекта: сохраните std::unique_ptr<State> и используйте std::make_unique<StateX>(), чтобы инициализировать его значением StateX, полученным из State, где последний является абстрактным базовым классом.

std::unique_ptr допускает заранее объявленные типы, но std::make_unique все еще требует хитрости из принятого ответа, так как ему нужен размер и конструктор StateX.

...