Циклический консекстр

Я хотел бы построить некоторые конечные автоматы, используя constexpr в C ++, который требует, чтобы состояния и их переходы также были constexpr. Если конечный автомат имеет циклическую часть (например, состояние 1 имеет переход в состояние 2, а состояние 2 имеет переход в состояние 1), то требуется циклический constexpr. Однако такой код, как следующий, не компилируется (MSVC 2017), так как constexpr должен быть инициализирован при объявлении:

class a
{
public:
constexpr a(a const & v) : v(v) {}
a const & v;
};

constexpr extern a x;
constexpr a y = a(x);
constexpr a x = a(y);

Есть ли обходной путь или план решения этой проблемы в будущем пересмотре стандарта C ++?

Изменить: на основе комментария Эренона, я попытался это:

class a
{
public:
constexpr a(a const & v) : v(v) {}
a const & v;
};

constexpr a x_getter();

constexpr a y_getter() {
return a(x_getter());
}

constexpr a x_getter() {
return a(y_getter());
}

constexpr a test = x_getter();

но это терпит неудачу с интересным предупреждающим сообщением: Warning C4591 'constexpr' call-depth limit of 512 exceeded а также expression did not evaluate to a constant ошибки в последней строке.

2

Решение

Вы можете скрыть x а также y внутри класса (или структуры). Даже если вы не хотите иметь рекурсивные ссылки, это будет полезно по причинам инкапсуляции информации:

#include <iostream>

class a
{
public:
// use `a const *` to avoid overriding default copy-constructor
constexpr a(a const *v_) : v(*v_) {}
a const & v;
};

struct state_machine
{
a const x,y;
constexpr state_machine() : x(&y), y(&x) {}
private:
// can't copy or move a state_machine (this implicitly deletes operator=):
state_machine(state_machine&&) = delete;
};

constexpr state_machine sm;

int main(int argc, char **argv) {
std::cout << "&x: " << &sm.x << ", &x.v: " << &sm.x.v << '\n';
std::cout << "&y: " << &sm.y << ", &y.v: " << &sm.y.v << '\n';
// state_machine sm2{sm}; // forbidden
}

Выше код был протестирован с g ++ версий 5.4.1 и 6.2.0 с использованием -std=c++11 а также -std=c++14, У меня нет MSVC, чтобы проверить это.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]