在项目编程中,经常会遇到类似这样的需求:当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.youkuaiyun.com/nanjiye/article/details/52138234
为实现上述功能,其实也可以舍弃Lambda表达式,直接使用std::function,同样可以达到效果。std::function的使用可参考我之前的博文:https://blog.youkuaiyun.com/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()