Может ли состояние поддерживаться через статические утверждения?
Наткнулся на это нужно некоторое время назад и был вынужден обойти это. Мне интересно, есть ли способ перенести состояние через проверку времени компиляции.
Так, например, мотивирующим примером будет то, как настроить счетчик, чтобы вы могли сделать что-то вроде:
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 ответ
Решение
Это невозможно во время компиляции:
- Объекты, такие как
myTest
создаются во время выполнения. - Объекты могут передаваться по ссылке или по значению в функции. При компиляции функции компилятор не может точно знать, на какой исходный объект он ссылался.
- Если ваше состояние будет объектно-независимым, и если оно будет выполнимо во время компиляции, состояние будет зависеть от порядка обращения к запросу состояния в каждом отдельно скомпилированном модуле, а не от потока выполнения (например, будет ли упоминаться состояние в цикле он будет иметь только одно постоянное значение в цикле, независимо от того, существует ли 1 или 1000 итераций).
Но это легко во время выполнения, с обычными переменными и утверждениями.