C++ Lamda表示式的一個妙用
技術標籤:C/C++
在專案程式設計中,經常會遇到類似這樣的需求:當verbosity設定大於等於1時,開啟debug列印;否則關閉列印。以下是一種常見的實現方法,因為log可能需要進行一些拼接或者計算,故在一個print_log函式中實現。但這樣做有一個問題,即使m_verbosity配置為0,print_log()這個函式作為debug的實參,也會被呼叫一次,只是最後在debug函式的執行過程中,沒有cout打印出來,這樣其實是浪費了CPU的效能的。
class MyTest { ... public: void debug(std::string msg) { if (this->m_verbosity < 1) return; cout << msg <<endl; } std::string print_log() { //your log } unsigned int m_verbosity; }; MyTest m_test; m_test.debug (print_log() );
那如何才能在m_verbosity配置為0時,讓CPU不再執行print_log()這個函式的呼叫。此時可以用Lambda表示式來實現,主要利用Lambda表示式的這一屬性:
Lambda表示式(或稱之為函式) 只有在被呼叫時,表示式中的內容,也就是{}中的程式碼 才會被 CPU 執行。
Lambda表示式,其實稱之為 Lambda自定義函式更合適。可以將一個Lambda表示式賦值給一個std::function<return_type ()> 型別的變數。
關於Lambda表示式,菜鳥教程頁面最下方的筆記可以看看。https://www.runoob.com/cplusplus/cpp-functions.html
百度百科 中有這樣一個地方的註釋 其實就是上述Lambda表示式的屬性https://baike.baidu.com/item/Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F/4585794?fr=aladdin
注意,如果使用 值捕獲,則print()函式必須是const才能編譯通過,否則會報‘this’ argument discards qualifiers [-fpermissive]的錯誤,參考 https://blog.csdn.net/nanjiye/article/details/52138234
//g++ -g -std=c++11 lambda.cpp -o sim #include <iostream> #include <string> #include <functional> using namespace std; // Lambda表示式(或稱之為函式) 只有在被呼叫時,表示式中的內容,也就是{}中的程式碼 才會被 CPU 執行 #define lazy_string(s) [&](){cout <<"verbosity=0 "<<endl; return s;} // 此處是引用捕獲 class MyTest { public: MyTest(unsigned int _verbosity) :m_verbosity(_verbosity) {} void debug(std::function<std::string()> msg)// Lambda表示式 賦值傳遞給了std::function<> 的形參 { if (this->m_verbosity < 3) { cout<<"debug function, verbosity <3. dont call print() " <<endl; return; } else { cout<<"debug function, verbosity >=3, "<<msg() <<endl;//此處 msg() 呼叫Lambda表示式 } } std::string print() const //如果使用 值捕獲,此處必須將print函式設定為const;如果使用引用捕獲,則不必是const { cout <<"call print() fcuntion "<<endl; return " print " ; } void set_verbosity(unsigned int _verbosity) { m_verbosity = _verbosity ; } unsigned int m_verbosity; }; int main(int argc, char* argv[]) { MyTest m_test(0); m_test.debug(lazy_string(m_test.print()) ); m_test.set_verbosity(5); m_test.debug( [=](){cout <<"verbosity=5" <<endl; return m_test.print();} ); //此處是 值捕獲 return 0; }