c++ - 编写一次性“如果”的最优雅方式
问题描述
由于 C++ 17 可以编写一个if
只执行一次的块,如下所示:
#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
吗?我希望不是。
解决方案
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;
}
};
推荐阅读
- r - Summarize Function dplyr 中的 n() 错误
- windows - 在 Windows 7 中使用 laravel 备份和恢复 PostgreSQL 数据库并设置 localhost 环境
- angularjs - 任务功能必须在 AngularJS 项目中使用 GULP 指定
- intellij-idea - 让 Intellij 显示隐式方法的快捷键是什么
- sql - 如何优化此查询的执行时间
- eclipse - 如何解决 eclipse 2020 中的单独包?
- html - Flexbox 和 100vh 高度:内容过多时页脚消失
- python - 将函数行明智地应用于熊猫数据框
- html - 在 Html/CSS/Bootstrap 4.0 中为计算器设计样式
- php - 未定义的索引 $_POST // 未捕获的 SyntaxError: Unexpected token < in JSON at position 0