Может ли состояние поддерживаться через статические утверждения?

Наткнулся на это нужно некоторое время назад и был вынужден обойти это. Мне интересно, есть ли способ перенести состояние через проверку времени компиляции.

Так, например, мотивирующим примером будет то, как настроить счетчик, чтобы вы могли сделать что-то вроде:

static_assert(foo() == 0, "..");
static_assert(foo() == 1, "..");
static_assert(foo() == 2, "..");

Где каждый последующий вызов увеличивал результат на 1. Я особенно заинтересован в выполнении этого во время компиляции. Я попытался настроить foo как constexpr с внутренним счетчиком, но затем установил ограничения только для чтения. Я хотел бы знать, возможно ли что-то в этом направлении с текущим стандартом C++.

int main() {

    static constexpr int counter = 0; 
    struct test
    {
        constexpr int foo(){return counter++;}
    };

    test myTest;

    static_assert(myTest.foo() == 0, "failed");
    static_assert(myTest.foo() == 1, "failed");

    return 0;
}

1 ответ

Решение

Это невозможно во время компиляции:

  1. Объекты, такие как myTest создаются во время выполнения.
  2. Объекты могут передаваться по ссылке или по значению в функции. При компиляции функции компилятор не может точно знать, на какой исходный объект он ссылался.
  3. Если ваше состояние будет объектно-независимым, и если оно будет выполнимо во время компиляции, состояние будет зависеть от порядка обращения к запросу состояния в каждом отдельно скомпилированном модуле, а не от потока выполнения (например, будет ли упоминаться состояние в цикле он будет иметь только одно постоянное значение в цикле, независимо от того, существует ли 1 или 1000 итераций).

Но это легко во время выполнения, с обычными переменными и утверждениями.

Другие вопросы по тегам