c++ - 最优雅的方式来写一次 'if'

标签 c++ if-statement c++17

从 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/

相关文章:

c++ - 获取谷歌测试异常抛出消息

javascript - 如果 css ("top") 等于或大于 -70(负值)

java - 关于java中的JOptionPane.showInputDialog的一些事情

c++ - 类无法访问其自己的私有(private)静态 constexpr 方法 - Clang 错误?

C++ 如何检测 Windows Server 2019?

c++ - 奇怪的 C/C++ 语法

c++ - 无法获得第二个 while 以正确循环

sql-server - sql SUM 结果过滤器(不需要 null 或 0)

c++ - 两个运算符(operator)的一些奇怪冲突<<

c++ - 如何将多个可变参数模板元组类合并为一个类?