C++ lambda 表达式中的捕获和参数有什么区别?
What is the difference between captures and parameters in a C++ laambda expression?
https://en.cppreference.com/w/cpp/algorithm/sort
std::array<int, 10> s = {5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
auto print = [&s](std::string_view const rem) {
for (auto a : s) {
std::cout << a << ' ';
}
std::cout << ": " << rem << '\n';
};
std::sort(s.begin(), s.end());
print("sorted with the default operator<");
例如,在这段代码中,为什么捕获“s”和参数“使用默认运算符<排序”?
为什么捕获“使用默认运算符<”而不是参数“s”排序?
捕获的值保留在 lambda 对象中,而函数参数仅用于调用。与任何函数一样,您可以多次调用 lambda 函数,每次调用其参数列表都有不同的参数列表。然而,lambda 对象恰好构造一次,此时捕获绑定到 lambda 的内部成员。
如果您将代码放入 https://cppinsights.io,您就会了解编译器如何处理您的 lambda 函数:
std::array<int, 10> s = {{5, 7, 4, 2, 8, 6, 1, 9, 0, 3}};
class __lambda_7_18
{
public:
inline /*constexpr */ void operator()(const std::basic_string_view<char, std::char_traits<char> > rem) const
{
{
std::array<int, 10> & __range1 = s;
int * __begin1 = __range1.begin();
int * __end1 = __range1.end();
for(; __begin1 != __end1; ++__begin1) {
int a = *__begin1;
std::operator<<(std::cout.operator<<(a), ' ');
}
}
std::operator<<(std::operator<<(std::operator<<(std::cout, ": "), std::basic_string_view<char, std::char_traits<char> >(rem)), '\n');
}
private:
std::array<int, 10> & s;
public:
__lambda_7_18(std::array<int, 10> & _s)
: s{_s}
{}
};
__lambda_7_18 print = __lambda_7_18{s};
print.operator()(std::basic_string_view<char, std::char_traits<char> >("sorted with the default operator<"));
如您所见,您的 print
lambda 是一个包含对捕获数组的引用的对象:s
。当您调用它时,它的 operator()
成员函数会用您传递给它的参数调用,这里是一个 std::string_view
和值 "sorted with the default operator<"
。您可以使用不同的值再次调用它。
lambda 不是函数,它是 class 带有将您的参数作为参数的 operator() 的函数。因此,捕获的变量将成为 class 的成员,因此可以重复使用,参数将成为运算符的参数。
https://en.cppreference.com/w/cpp/algorithm/sort
std::array<int, 10> s = {5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
auto print = [&s](std::string_view const rem) {
for (auto a : s) {
std::cout << a << ' ';
}
std::cout << ": " << rem << '\n';
};
std::sort(s.begin(), s.end());
print("sorted with the default operator<");
例如,在这段代码中,为什么捕获“s”和参数“使用默认运算符<排序”? 为什么捕获“使用默认运算符<”而不是参数“s”排序?
捕获的值保留在 lambda 对象中,而函数参数仅用于调用。与任何函数一样,您可以多次调用 lambda 函数,每次调用其参数列表都有不同的参数列表。然而,lambda 对象恰好构造一次,此时捕获绑定到 lambda 的内部成员。
如果您将代码放入 https://cppinsights.io,您就会了解编译器如何处理您的 lambda 函数:
std::array<int, 10> s = {{5, 7, 4, 2, 8, 6, 1, 9, 0, 3}};
class __lambda_7_18
{
public:
inline /*constexpr */ void operator()(const std::basic_string_view<char, std::char_traits<char> > rem) const
{
{
std::array<int, 10> & __range1 = s;
int * __begin1 = __range1.begin();
int * __end1 = __range1.end();
for(; __begin1 != __end1; ++__begin1) {
int a = *__begin1;
std::operator<<(std::cout.operator<<(a), ' ');
}
}
std::operator<<(std::operator<<(std::operator<<(std::cout, ": "), std::basic_string_view<char, std::char_traits<char> >(rem)), '\n');
}
private:
std::array<int, 10> & s;
public:
__lambda_7_18(std::array<int, 10> & _s)
: s{_s}
{}
};
__lambda_7_18 print = __lambda_7_18{s};
print.operator()(std::basic_string_view<char, std::char_traits<char> >("sorted with the default operator<"));
如您所见,您的 print
lambda 是一个包含对捕获数组的引用的对象:s
。当您调用它时,它的 operator()
成员函数会用您传递给它的参数调用,这里是一个 std::string_view
和值 "sorted with the default operator<"
。您可以使用不同的值再次调用它。
lambda 不是函数,它是 class 带有将您的参数作为参数的 operator() 的函数。因此,捕获的变量将成为 class 的成员,因此可以重复使用,参数将成为运算符的参数。