可以跨静态断言维护状态吗?

Can state be maintained across static asserts?

不久前遇到了这个需求,被迫解决它。我想知道是否有一种方法可以在编译时检查中携带状态。

例如,一个激励性的示例是如何设置计数器以便您可以执行以下操作:

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 等对象在运行时实例化。
  2. 对象可以通过引用或值传递给函数。编译函数时,编译器无法确定它引用的是哪个原始对象。
  3. 如果你的状态是对象独立的,并且在编译时可行,那么状态将取决于在每个单独编译的单元中遇到状态查询的顺序,而不是执行流程(例如将状态在循环中被引用,它在整个循环中只有一个常量值,无论有 1 次还是 1000 次迭代)。

但在运行时很容易,使用普通变量和断言。