9

在 javascript 中有这个甜蜜的函数window.setTimeout( func, 1000 ) ;,它将在 1000 毫秒后异步调用。func

我想在 C++ 中做类似的事情(没有多线程),所以我把一个示例循环放在一起:

    #include <stdio.h>

    结构回调
    {
      // _time_ 这个函数将被执行。
      双执行时间;

      // execTime 过后要执行的函数
      无效*函数;
    } ;

    // 要执行的示例函数
    无效的去()
    {
      放(“去”);
    }

    // 全局程序范围的时间感
    双倍时间 ;

    主函数()
    {
      // 启动定时器
      时间 = 0 ;

      // 做一个示例回调
      回调 c1 ;
      c1.execTime = 10000 ;
      c1.func = 去;

      而(一)
      {
        // 是时候执行它了
        如果(时间> c1.execTime)
        {
          c1.func ; // !! 不工作!
        }

        时间++;
      }
    }

我怎样才能使这样的工作?

4

5 回答 5

12

在 C++11 出来之后,如果你使用的是 c++11 支持的编译器,你可以使用lambda可变参数模板函数异步线程在 c++ 中轻松模拟 javascript 函数。

这是我为 setTimeOut 编写的代码,它已经过全面测试:

setTimeOut 函数的定义:

    #include <windows.h>//different header file in linux
    #include <future>
    using namespace std;

    template <typename... ParamTypes>
    void setTimeOut(int milliseconds,std::function<void(ParamTypes...)> func,ParamTypes... parames)
    {   
        std::async(std::launch::async,[=]()
        {       
            Sleep(milliseconds);
            func(parames...); 
        });
     };

这个函数通过使用 c+11 的可变参数模板接受可变参数,代码可以告诉你如何使用它:

    #include <iostream>
    #include <thread>
    #include <string>
    #include <functional>
    #include <windows.h>

    #include <future>
    using namespace std;
    int main() 
    {
        std::mutex locker;
        std::function<void()> func1 = [&]()
        {
            std::unique_lock<std::mutex> lk(locker);
            std::cout << "func 1 is trigged:" << "   no parameter" << std::endl;
            lk.unlock();
        };      
        std::function<void(int)> func2 = [&](int param)
        {
            std::unique_lock<std::mutex> lk(locker);
            std::cout << "func 2 is trigged:" << "   int: " << param <<std::endl;
            lk.unlock();
        };
        std::function<void(int,std::string)> func3 = [&](int param1,std::string param2)
        {
            std::unique_lock<std::mutex> lk(locker);
            std::cout << "func 3 is trigged:" << "   int: " << param1 << ";  string: " << param2 << std::endl;
            lk.unlock();
        };

        for(int index=0;index<100;index++)
        {
            std::unique_lock<std::mutex> lk1(locker);
            std::cout << "set timer for func  1" << std::endl;
            lk1.unlock();
            setTimeOut<>(1000,func1);

            std::unique_lock<std::mutex> lk2(locker);
            std::cout << "set timer for func  2" << std::endl;
            lk2.unlock();
            setTimeOut<int>(2000,func2,10000);

            std::unique_lock<std::mutex> lk3(locker);
            std::cout << "set timer for func  3" << std::endl;
            lk3.unlock();
            setTimeOut<int,std::string>(5000,func3,10000,"ddddd");
        }
        Sleep(10000000);
    }
于 2013-12-06T22:58:11.767 回答
5

Callback::func类型,void (*)()

struct Callback
{
    double execTime;
    void (*func)();
};

你可以这样调用函数:

c1.func();

另外,不要忙等。ualarm在 Linux 或CreateWaitableTimerWindows 上使用。

于 2010-03-20T22:57:19.297 回答
1

我只是在这里修复您的代码,而不是跳出框框思考。其他答案已经为此提供了一些指示。

为了更好的类型安全,你应该声明你的回调指针如下:

  // The function to execute after execTime has passed
  void (*func)() ;

然后,将其称为:

  c1.func() ;
于 2010-03-20T23:00:05.407 回答
1

在 C++ 本身中,你是非常有限的。您需要一个多线程操作系统,您可以在其中使用睡眠功能(您仍然可以让程序继续使用单独的线程运行),或者您需要一个消息传递系统,如 Windows。

我看到您可以做某事的唯一另一种方法是在代码中分散大量调用,这些调用调用返回 true 或 false 的函数,具体取决于时间是否已过。当然,该函数可以是回调,但您仍需要定期调用它。

于 2010-03-20T22:53:58.367 回答
0

另一个(更好的)答案是使用<functional>C++ 中的标头,并像这样声明函数:

#include <functional>

function<void ()> func ;

// assign like
func = go ; //go is a function name that accepts 0 parameters
// and has return type void

// exec like
func() ;
于 2011-12-14T15:57:27.830 回答