一次性写“ if”的最优雅方式 [英] Most elegant way to write a one-shot 'if'

查看:66
本文介绍了一次性写“ if”的最优雅方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自C ++ 17起,我们就可以编写一个 if 块,该块将完全像这样执行一次:

Since C++ 17 one can write an if block that will get executed exactly once like this:

#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 结尾?

I know I might be overthinking this, and there are other ways to solve this, but still - is it possible to write this somehow like this, so there is no need of the do_once = false at the end?

if (DO_ONCE) {
    // Do stuff
}

我在考虑一个辅助函数, do_once() ,其中包含静态布尔do_once ,但是如果我想在不同的地方使用相同的功能怎么办?也许这是 #define 的时间和地点吗?

I'm thinking a helper function, do_once(), containing the static bool do_once, but what if I wanted to use that same function in different places? Might this be the time and place for a #define? I hope not.

推荐答案

使用 std :: exchange

if (static bool do_once = true; std::exchange(do_once, false))



< hr>

您可以缩短反转真值的时间:


You can make it shorter reversing the truth value:

if (static bool do_once; !std::exchange(do_once, true))

但是如果您使用的是很多,不要看中并创建一个包装器:

But if you are using this a lot, don't be fancy and create a wrapper instead:

struct Once {
    bool b = true;
    explicit operator bool() { return std::exchange(b, false); }
};

并像这样使用它:

if (static Once once; once)

不应假定变量在条件之外被引用,因此名称并不能给我们带来多少好处。从其他语言中汲取灵感,例如 Python 赋予 _ 标识符特殊的含义,我们可以这样写:

The variable is not supposed to be referenced outside the condition, so the name does not buy us much. Taking inspiration from other languages like Python which give a special meaning to the _ identifier, we may write:

if (static Once _; _)






进一步的改进:利用BSS部分(@Deduplicator),避免在我们已经运行时写入内存(@ShadowRanger),并在要进行多次测试时给出分支预测提示(例如,如问题所示):


Further improvements: take advantage of the BSS section (@Deduplicator), avoid the memory write when we have already run (@ShadowRanger), and give a branch prediction hint if you are going to test many times (e.g. like in the question):

// 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;
    }
};

这篇关于一次性写“ if”的最优雅方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆