【问题标题】:C++: compile-time checking for matching pairs of function calls?C++:编译时检查匹配的函数调用对?
【发布时间】:2020-07-06 06:42:56
【问题描述】:

我有一个用于计时代码块的计时器类。基本上是这样的:

timer.start();
////do something
timer.end();

我正在寻找一种 编译时 方法来确保 start 和 end 调用都存在,并且在范围内。甚至是骇人听闻的方法。

这是我的意思的一个例子......如果调用“end()”而不是“start()”,这将产生编译时错误,因为隐藏变量“foo”的方式是初始化。

#define start_macro bool foo = false; timer.start();
#define end_macro foo = true; timer.end();

//start_macro
////do something
end_macro //generates error because start_macro not called, thus foo not declared

但显然该方法的应用是有限的,因为如果 end() 是未调用的函数,它不会产生错误。

是否有任何聪明的方法可以确保在编译时按顺序和范围调用这两个函数?我对任何运行时检查方法都不感兴趣...我想要一种更快的方法来捕获丢失的调用。

【问题讨论】:

  • 使用 RAII - 一个在构建时启动计时器并在销毁时结束的对象。然后在与您正在计时的任何内容相同的块中包含该类型的对象。与lock_guard 等标准类的想法相同。

标签: c++ function compilation


【解决方案1】:

不幸的是,没有通用的解决方案。您需要以某种方式告诉编译器,匹配的函数是什么。而且,您永远不知道关闭函数应该在哪个范围内。所以,相当困难甚至不可能。

更好的方法是使用带有构造函数/析构函数解决方案的包装类。构造函数将启动计时器,而析构函数将停止它。但那是运行时。 . .

另一种解决方案是编写宏,在这些语句之间注入计时器启动和停止之间的代码。但真的不好,无论如何,不​​推荐使用宏。也可能有一种模板方法,试图模仿它。

但要判断这一点,你需要指定更多的要求。

【讨论】:

    【解决方案2】:

    您可以使用 RAII,定义一个类包装器,例如ScopedTimer,它的构造函数调用start(),而析构函数调用end()。将您的Timer::start()Timer::end() 设为受保护,并将ScopedTimer 设为Timer 的好友,这样只有ScopedTimer 才能调用它们。

    没有运行时检查。而且也没有编译时检查。它只是使编写调用其中一个函数而不调用另一个函数的代码变得不可能。

    class  ScopedTimer {
     public:
      explicit ScopedTimer(Timer *tm)
          : tm_(tm)  {
        this->tm_->start();
      }
      ~ScopedTimer() { this->tm_->stop(); }
     protected:
      Timer* tm;
    };
    
    // Your code will be like this:
    { // This pair of braces defines the scope that you want to measure.
      ScopedTimer st(&timer);
      ////do something
    }
    
    

    【讨论】:

      【解决方案3】:

      正如肖恩在评论中指出的那样。为了确保计时器已经启动,您只需将计时器的开始放在构造函数中并在析构函数中停止。我在为我的项目进行测量时使用了这种方法。

      class Timer {
       public:
           Clock clock;
           Timer() { clock.start(); }
           ~Timer() 
           { 
               clock.stop(); 
               saveMeasurements(); 
           }
       private:
           void saveMeasurements(); //save measurements to file
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-29
        • 2013-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多