C++ Lamda表达式的一个妙用

在项目编程中,经常会遇到类似这样的需求:当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

为实现上述功能,其实也可以舍弃Lambda表达式,直接使用std::function,同样可以达到效果。std::function的使用可参考我之前的博文:https://blog.csdn.net/zgcjaxj/article/details/109150077

//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 < 1)
        {
            cout<<"debug function, verbosity <1.  dont call print() " <<endl;
            return;
        }
        else
        {
            cout<<"debug function, verbosity >=1, "<<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(1);
    m_test.debug( [=](){cout <<"verbosity=1" <<endl; return m_test.print();} ); //此处是 值捕获

    m_test.set_verbosity(0);
    m_test.debug( std::bind(&MyTest::print, &m_test)  ); //std::bind(&MyTest::print, &m_test)的返回值为 std::function

    return 0;
}

 结果如下:

debug function, verbosity <1.  dont call print() 
verbosity=1
call print() fcuntion 
debug function, verbosity >=1,  print 
debug function, verbosity <1.  dont call print()

猜你喜欢

转载自blog.csdn.net/zgcjaxj/article/details/113427575