起因
在阅读.Net Runtime源码的时候,发现C++有使用Lambda表达式,便学习了怎么使用的.C++的Lambda表达式和C#还是不太一样.C++中Lambda有3种方式.
- [] 没有捕获,和普通函数一样
- [=] 按值捕获
- [&] 按引用捕获
#include <iostream>
#include <functional>
using namespace std;
int test(int num)
{
return num + 100;
}
int sum_func(int a, function<int(int)> calc)
{
return calc(a);
}
int main(int argc, char* argv[])
{
auto func = [](int num) { cout << "num=" << num << endl; };
func(5);
auto func2 = [](int num) { return num += 100; };
int sum = func2(200);
cout << "sum=" << sum << endl;
int val1 = sum_func(100, [&](int num) { return num + 100; });
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)
{
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))
{
char_t* fileNameChar = data.cFileName;
while (*fileNameChar)
{
*fileNameChar = towlower(*fileNameChar);
fileNameChar++;
}
if (should_add(data.cFileName))
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;
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);
for (const string_t& dir : { core_libraries, core_root })
{
if (dir.empty())
continue;
assert(dir.back() == pal::dir_delim);
string_t tmp = pal::build_file_list(dir, ext, [&](const char_t* file)
{
string_t file_local{ file };
if (pal::string_ends_with(file_local, ext_len, ext))
file_local = file_local.substr(0, file_local.length() - ext_len);
return name_set.insert(file_local).second;
});
tpa_list << tmp;
}
}
}