gpt4 book ai didi

c++ - 在 lambda 闭包上应用 move

转载 作者:太空狗 更新时间:2023-10-29 20:22:40 25 4
gpt4 key购买 nike

这可能是一个概念性问题。我正在实现采用 lambda 的功能作为参数。但是,我无法理解 lambda 的确切类型.例如:

auto T = [] () { printf("hello world\n"); };
auto F = move(T);
T(); // print "hello world"
F(); // print "hello world"

我打电话后想moveT , T 的内容消失了。换句话说,我期望以下行为:

function<void> T = [] () { printf("hello world\n");};
auto F = move(F);
F(); // print "hello world"
T(); // throw error

回到最初的问题,传递/分配 lambda 的最佳实践是什么?给function<void()>的类(class)成员?我看到许多不同的答案,有些使用 const function<void()>&和其他人建议模板 F&&

struct Foo {

function<void()> f;

// Option 1:
void set_f(const function<void()>& in) {f=in;}

// Option 2: template
template <typename F>
void set_f(F&& in) { // what to write here??? }
}

这两个选项是否足够通用以捕获大多数输入类型?

最佳答案

您似乎对编译器对 lambda 表达式的处理有基本的误解。 Lambda 表达式被转换为具有唯一名称的仿函数。当您调用 lambda 时,您只是在调用仿函数的 operator()

所以你第一个例子中的 lambda 会创建这样的东西

struct __uniquely_named_lambda
{
void operator()() const
{
printf("hello world\n");
}
};

如果这个 lambda 正在存储任何状态,那么 move 将移动状态,但是你的 lambda 是无状态的,所以 move 什么都不做;您不能剥离 operator() 的主体并将其移动到其他地方。

例如,这些语句将产生输出 4 0 4

std::string s{"Test"};
auto T = [s]() { std::cout << s.size() << ' '; }; // make a copy of s
T();
auto F = std::move(T);
T();
F();

Live demo


std::function 是一个容器,可以接受任何与指定签名匹配的 callable,而您的 lambda 就是这样的一个。当您移动 std::function 时,您将它存储的可调用目标移动到目的地。尝试在原始对象上调用目标将抛出 bad_function_call,这与 movea lambda 非常不同。


我会把set_f成员函数写成

template <typename F>
void set_f(F&& in)
{
f = std::forward<F>(in);
}

F 在您的示例中是转发引用,这意味着它将能够接受调用者传递的左值或右值。然后赋值将复制赋值或移动赋值参数。

关于c++ - 在 lambda 闭包上应用 move,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36855010/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com