如何在C++中使用Lambda
起因
在阅读.Net Runtime源码的时候,发现C++有使用Lambda表达式,便学习了怎么使用的.C++的Lambda表达式和C#还是不太一样.C++中Lambda有3种方式.- [] 没有捕获,和普通函数一样
- [=] 按值捕获
- [&] 按引用捕获
简单学习,如何在C++使用Lambda
#include <iostream>
#include <functional>
using namespace std;
int test(int num)
{
return num + 100;
}
int sum_func(int a, function<int(int)> calc) //使用function<>需要引入头文件functional
{
return calc(a);
}
int main(int argc, char* argv[])
{
auto func = [](int num) { cout << "num=" << num << endl; }; //创建一个没有返回值lambda表达式
func(5); //调用Lambda
auto func2 = [](int num) { return num += 100; }; //创建一个返回int类型的lambda表达式
int sum = func2(200);
cout << "sum=" << sum << endl;
int val1 = sum_func(100, [&](int num) { return num + 100; }); //将lambda表达式作为参数
int val2 = sum_func(100, test); //把函数作为参数
cout << "val1=" << val1 << endl;
cout << "val2=" << val2 << endl;
cin.get();
return 0;
}
.Net Runtime源码是这样使用Lambda的
inline string_t build_file_list(
const string_t& dir, //传入路径
const char_t* ext, //扩展名
std::function<bool(const char_t*)> should_add) //接收一个函数或者lambda表达式
{
assert(ext != nullptr);
string_t dir_local = dir;
dir_local.append(W("*"));
dir_local.append(ext);
WIN32_FIND_DATA data;
HANDLE findHandle = ::FindFirstFileW(dir_local.data(), &data); //根据路径查找路径下第一个文件
if (findHandle == INVALID_HANDLE_VALUE)
return {};
stringstream_t file_list;
do
{
if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
// ToLower for case-insensitive comparisons
char_t* fileNameChar = data.cFileName; //获取文件名
while (*fileNameChar)
{
*fileNameChar = towlower(*fileNameChar);
fileNameChar++;
}
if (should_add(data.cFileName)) //调用lambda或者函数
file_list << dir << data.cFileName << env_path_delim;
}
} while (FALSE != ::FindNextFileW(findHandle, &data)); //继续下一个文件
::FindClose(findHandle); //关闭句柄,如果使用完毕不对句柄进行释放的话,就容易造成内存泄露
return file_list.str();
}
int mian(int argc, char* argv[]) //源码中不是这样的.
{
std::set<string_t> name_set;
pal::stringstream_t tpa_list;
// Iterate over all extensions.
for (const char_t* const* curr_ext = tpa_extensions; *curr_ext != nullptr; ++curr_ext)
{
const char_t* ext = *curr_ext;
const size_t ext_len = pal::strlen(ext);
// Iterate over all supplied directories.
for (const string_t& dir : { core_libraries, core_root })
{
if (dir.empty())
continue;
assert(dir.back() == pal::dir_delim);
//build_file_list 第一个参数为路径 第二个参数文件扩展名 第三个为lambda表达式,按引用捕获
string_t tmp = pal::build_file_list(dir, ext, [&](const char_t* file)
{
string_t file_local{ file };
// Strip the extension.
if (pal::string_ends_with(file_local, ext_len, ext))
file_local = file_local.substr(0, file_local.length() - ext_len);
// Return true if the file is new.
return name_set.insert(file_local).second;
});
// Add to the TPA.
tpa_list << tmp;
}
}
}
秋风
2021-12-12