1. 程式人生 > 其它 >C++ Lamda表示式的一個妙用

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;
}