[英]C++: compile-time checking for matching pairs of function calls?
我有一個計時器 class 我用來計時代碼塊。 基本上是這樣的:
timer.start();
////do something
timer.end();
我正在尋找一種編譯時方法來確保開始和結束調用都存在,並且在 scope 內。 甚至是駭人聽聞的方法。
這是我的意思的一個例子......如果調用“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() 是未調用的 function 則不會產生錯誤。
有沒有什么聰明的方法可以確保在編譯時按順序和在 scope 中調用這兩個函數? 我對任何運行時檢查方法都不感興趣……我想要一種更快的方法來捕捉丟失的呼叫。
不幸的是,沒有通用的解決方案。 您需要以某種方式告訴編譯器,匹配的函數是什么。 而且,你永遠不知道,scope 應該在哪個 function 結束。 所以,相當困難到不可能。
更好的方法是使用帶有構造函數/析構函數解決方案的包裝器 class。 構造函數將啟動計時器,而析構函數將停止它。 但那是運行時。 . .
另一種解決方案是編寫宏,在這些語句之間注入計時器啟動和停止之間的代碼。 但真的不好,無論如何,不推薦使用宏。 也可能有一種模板方法,試圖模仿它。
但是要對此進行判斷,您需要指定更多要求。
您可以使用 RAII,定義一個 class 包裝器,例如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
}
正如肖恩在評論中指出的那樣。 為了確保計時器已經啟動,您只需將計時器的開始放在構造函數中並在析構函數中停止。 我在為我的項目進行測量時使用了這種方法。
class Timer {
public:
Clock clock;
Timer() { clock.start(); }
~Timer()
{
clock.stop();
saveMeasurements();
}
private:
void saveMeasurements(); //save measurements to file
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.