在 C++20/C++23 中将参数完美转发到 lambda 捕获的最简洁方法是什么?我的意思是在协程对象内部通过复制捕获右值并通过引用捕获左值:
struct A { int _value{0}; };
auto foo = []<typename T>(T&& a) {
return [a = std::forward<T>(a)]() mutable {
++a._value;
std::cout << a._value << "\n";
};
};
A my_a;
auto capture_as_lvalue = foo(my_a);
capture_as_lvalue(); // Prints `1`.
capture_as_lvalue(); // Prints `2`.
capture_as_lvalue(); // Prints `3`.
std::cout << my_a._value << "\n"; // Should print `3`.
auto capture_as_rvalue = foo(A{});
capture_as_rvalue(); // Prints `1`.
Run Code Online (Sandbox Code Playgroud)
这个答案似乎表明上面的内容应该有效,但是上面的程序(https://godbolt.org/z/Mz3caah5o)导致
1
2
3
0 <- should be 3
1 …Run Code Online (Sandbox Code Playgroud) 下面的代码标准正确吗?(天马行空)
即 by-ref 捕获表示临时的转发引用,并在同一表达式中从函数返回结果 lambda 值。
当然,存储 lambda 以供以后使用会使它包含一个悬空引用,但我指的是main.
我的疑虑与这个 SO answer和潜在的这种语言缺陷有关。具体来说,有一个令人生畏的评论说“标准引用中的引用捕获生命周期规则捕获了变量,而不是数据及其范围” ——这似乎是说捕获的临时引用在我的代码中可能是无效的。
#include <stdlib.h>
#include <string.h>
#include <cassert>
template<typename F>
auto invoke(F&& f)
{
return f();
}
template<typename F>
auto wrap(F&& f)
{
return [&f]() {return f();}; // <- this by-ref capture here
}
int main()
{
int t = invoke(wrap(
[]() {return 17;}
));
assert(t == 17);
return t;
}
Run Code Online (Sandbox Code Playgroud) 我知道sort范围内的算法(例如)支持投影,但在我看来,没有办法为视图获得该功能......我对吗?
作为示例,请考虑以下工作代码:
#include <algorithm>
#include <ranges>
#include <vector>
#include <iostream>
enum Color {
Red,
Green,
Blue
};
struct Cat {
int age;
Color color;
};
int main() {
std::vector<Cat> cats{{.age = 10,.color=Color::Red}, {.age = 20,.color=Color::Blue}, {.age = 30,.color=Color::Green}};
auto is_red = [](const auto& cat) {return cat.color == Color::Red;};
for (const auto& cat: cats | std::views::filter(is_red)) {
std::cout << cat.age << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法删除 lambda 并执行以下操作:
for (const auto& cat: cats | std::views::filter(&Cat::color, Color::Red) {
Run Code Online (Sandbox Code Playgroud)
注意:我的问题是成员变量投影,但显然在实际代码中也需要成员函数调用。
所以我有一个完美的转发器,我想在 lambda 中适当地捕获它,以便复制 R 值,并通过引用捕获 L 值。然而,简单地使用 std::forward 并不能完成这项工作,如以下代码所示:
#include<iostream>
class testClass
{
public:
testClass() = default;
testClass( const testClass & other ) { std::cout << "COPY C" << std::endl; }
testClass & operator=(const testClass & other ) { std::cout << "COPY A" << std::endl; }
};
template< class T>
void testFunc(T && t)
{ [test = std::forward<T>(t)](){}(); }
int main()
{
testClass x;
std::cout << "PLEASE NO COPY" << std::endl;
testFunc(x);
std::cout << "DONE" << std::endl;
std::cout << "COPY …Run Code Online (Sandbox Code Playgroud)