gpt4 book ai didi

c++ - 在可移动类型的构造函数 lambda 中安全使用 captured this

转载 作者:行者123 更新时间:2023-11-30 04:52:28 24 4
gpt4 key购买 nike

在我们需要在可移动类型中捕获 this 的构造函数中创建 lambda 的地方使用这个人为设计的代码:

#include <functional>
#include <string>
#include <iostream>

using namespace std::string_literals;

namespace
{
class foo
{
public:
template <typename T>
explicit foo(std::string key, T val) :
key_{std::move(key)}
{
f_ = [this, v = std::move(val)]() {
std::cout << key_ << ": " << v << std::endl;
};
}

void print()
{
f_();
}

private:
std::function<void ()> f_;
std::string key_;
};
}

int main()
{
auto f1 = foo("hello", "goodbye"s);
auto f2 = std::move(f1);
f2.print();

return EXIT_SUCCESS;
}

在此示例中,我们使用 lambda 进行类型删除,但这并不重要 - 重要的是我们在构造函数的 lambda 中捕获 this

Running this将产生:

: goodbye

这(我认为)是因为正在打印的 key_ 成员是移出的 f1::key_ 的空壳,即捕获的 this 指针仍指向 f1,尽管现在位于 f2 内。

我可以想到几种(笨拙的)解决方法,这些方法是针对特定情况的,但是是否有标准/通用/更好/等等。从 lambda 内部有效引用拥有实例的方法?

最佳答案

一个简单的解决方案可能是避免捕获 this 并将其作为参数提供给您的函数对象。通过这种方式,您的函数对象可以自由复制和移动,而无需考虑哪个实例拥有哪个函数对象。当前所有者可以在需要调用函数时将自身传递给该函数。

例如,您的原始示例可能如下所示:

#include <iostream>
#include <functional>
#include <string>

class foo
{
public:
template <typename T>
explicit foo(std::string key, T val) :
key_{ std::move(key) }
{
f_ = [v = std::move(val)](foo * const this_ptr) {
std::cout << this_ptr->key_ << ": " << v << std::endl;
};
}

void print()
{
f_(this);
}

private:
std::function<void(foo *)> f_;
std::string key_;
};

关于c++ - 在可移动类型的构造函数 lambda 中安全使用 captured this,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54354615/

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