从 C++ 17 开始,人们可以编写一个 if
block ,该 block 将像这样执行一次:
#include <iostream>
int main() {
for (unsigned i = 0; i < 10; ++i) {
if (static bool do_once = true; do_once) { // Enter only once
std::cout << "hello one-shot" << std::endl;
// Possibly much more code
do_once = false;
}
}
}
我知道我可能想多了,还有其他方法可以解决这个问题,但是 - 是否可以这样写,所以不需要 do_once = false
最后?
if (DO_ONCE) {
// Do stuff
}
我正在考虑一个辅助函数 do_once()
,它包含 static bool do_once
,但是如果我想在不同的地方使用相同的函数怎么办?这可能是 #define
的时间和地点吗?我希望不会。
最佳答案
使用 std::exchange
:
if (static bool do_once = true; std::exchange(do_once, false))
你可以缩短反转真值:
if (static bool do_once; !std::exchange(do_once, true))
但如果你经常使用这个,不要花哨,而是创建一个包装器:
struct Once {
bool b = true;
explicit operator bool() { return std::exchange(b, false); }
};
并像这样使用它:
if (static Once once; once)
这个变量不应该在条件之外被引用,所以这个名字对我们没有太大的意义。从其他语言中汲取灵感,例如 Python这给 _
标识符赋予了特殊含义,我们可以这样写:
if (static Once _; _)
进一步改进:利用 BSS 部分 (@Deduplicator),避免在我们已经运行时写入内存 (@ShadowRanger),如果您要进行多次测试(例如,像在问题):
// GCC, Clang, icc only; use [[likely]] in C++20 instead
#define likely(x) __builtin_expect(!!(x), 1)
struct Once {
bool b = false;
explicit operator bool()
{
if (likely(b))
return false;
b = true;
return true;
}
};
关于c++ - 最优雅的方式来写一次 'if',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56738380/