可以跨静态断言维护状态吗?
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;
}
这在编译时是不可行的:
-
myTest
等对象在运行时实例化。
- 对象可以通过引用或值传递给函数。编译函数时,编译器无法确定它引用的是哪个原始对象。
- 如果你的状态是对象独立的,并且在编译时可行,那么状态将取决于在每个单独编译的单元中遇到状态查询的顺序,而不是执行流程(例如将状态在循环中被引用,它在整个循环中只有一个常量值,无论有 1 次还是 1000 次迭代)。
但在运行时很容易,使用普通变量和断言。
不久前遇到了这个需求,被迫解决它。我想知道是否有一种方法可以在编译时检查中携带状态。
例如,一个激励性的示例是如何设置计数器以便您可以执行以下操作:
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;
}
这在编译时是不可行的:
-
myTest
等对象在运行时实例化。 - 对象可以通过引用或值传递给函数。编译函数时,编译器无法确定它引用的是哪个原始对象。
- 如果你的状态是对象独立的,并且在编译时可行,那么状态将取决于在每个单独编译的单元中遇到状态查询的顺序,而不是执行流程(例如将状态在循环中被引用,它在整个循环中只有一个常量值,无论有 1 次还是 1000 次迭代)。
但在运行时很容易,使用普通变量和断言。