如何只执行一段代码?

Dar*_*zen 17 c++ static global-variables

我有一个应用程序,它有几个功能.可以根据用户输入多次调用每个函数.但是,我需要在函数中执行一小段代码,最初只在应用程序启动时执行.当在稍后的时间点再次调用此相同的函数时,不得执行此特定代码段.代码在VC++中.请告诉我最有效的处理方法.

Bas*_*tch 24

将全局静态对象与构造函数(之前调用过main)一起使用?或者只是在例程中

static bool initialized;
if (!initialized) {
   initialized = true;
   // do the initialization part
}
Run Code Online (Sandbox Code Playgroud)

很少有这种情况不够快!


附加物

在多线程环境中,这可能还不够:

您可能还对pthread_once或GCC的constructor功能__attribute__感兴趣.

使用C++ 11,您可能需要std :: call_once.

如果可以从多个线程调用函数,则可能需要使用<atomic>并且可能声明static volatile std::atomic_bool initialized;(但需要注意).

但是这些可能在您的系统上不可用; 它们在Linux上可用!

  • 这不会像在多线程设置中那样起作用,但是应该适合大多数用例 (2认同)
  • AFAIK,一个`static`变量被初始化为全零位,对于`bool`来说这是`false` (2认同)
  • 从 C++11 开始,这是线程安全的。是的,静态变量是零初始化的。然而,我仍然认为养成始终显式初始化原始类型的习惯是件好事;这样,如果将其重构为不隐式初始化,您以后就不会遇到恐惧。 (2认同)

Bed*_*ver 24

使用lambda函数的紧凑版本:

void foo()
{
    static bool once = [](){
        cout << "once" << endl;
        return true;
    } ();
    cout << "foo" << endl;
}
Run Code Online (Sandbox Code Playgroud)

当静态变量初始化为lambda函数的返回值时,lambda函数中的代码只执行一次.只要您的编译器支持线程安全的静态初始化,它应该是线程安全的.

  • 这将显示警告“警告:未使用的变量‘一次’[-Wunused-variable]”。对于 C++17,您可以使用 [[maybe_unused]] 来抑制它。 (3认同)
  • 如果将由此生成的汇编代码与使用 std::call_once 时生成的汇编代码进行比较,那么这段代码看起来要好得多!https://godbolt.org/z/s3YPeb (2认同)

Sor*_*ren 23

使用C++ 11 - 使用 std::call_once

#include <mutex>

std::once_flag onceFlag;

{
    ....
    std::call_once ( onceFlag, [ ]{ /* my code body here runs only once */ } );
    ....
}
Run Code Online (Sandbox Code Playgroud)

  • 我正在使用它来产生很大的影响,我唯一要做的就是改进它,如果你在函数中将你的 once_flag 声明为静态,它只会被初始化一次,你在 call_once 中的代码只会运行一次,但你可以将所有代码保持在同一范围内。 (2认同)

Aby*_*byx 16

您可以使用本地静态变量:

void foo()
{
     static bool wasExecuted = false;
     if (wasExecuted)
         return;
     wasExecuted = true;

     ...
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*ane 6

除了@Basile 的回答之外,您还可以使用 lambda 来封装静态变量,如下所示:

if ([] {
    static bool is_first_time = true;
    auto was_first_time = is_first_time;
    is_first_time = false;
    return was_first_time; } ()) 
{ 
    // do the initialization part
}
Run Code Online (Sandbox Code Playgroud)

这使得转换为通用宏变得容易:

#define FIRST_TIME_HERE ([] { \
    static bool is_first_time = true; \
    auto was_first_time = is_first_time; \
    is_first_time = false; \
    return was_first_time; } ())
Run Code Online (Sandbox Code Playgroud)

可以根据需要放置在任何您想要调用的地方:

if (FIRST_TIME_HERE) {
    // do the initialization part
}
Run Code Online (Sandbox Code Playgroud)

为了更好地衡量,原子缩短了表达式并使其成为线程安全的:

#include <atomic>
#define FIRST_TIME_HERE ([] { \
    static std::atomic<bool> first_time(true); \
    return first_time.exchange(false); } ())
Run Code Online (Sandbox Code Playgroud)


aah*_*134 5

你能做到吗

有一个函数返回bool或一些名为init的数据类型

我通过这种方式实现了这一点,你需要静态bool来实现它

bool init()
{
  cout << "Once " <<endl;
  return true||false;// value isn't matter
}

void functionCall()
{
    static bool somebool = init(); // this line get executed once
    cout << "process " <<endl;
}

int main(int argc, char *argv[])
{
    functionCall();
    functionCall();
    functionCall();

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)