如何捕获std :: unique_ptr“by move”对于std :: for_each中的lambda [英] How to capture std::unique_ptr "by move" for a lambda in std::for_each

查看:114
本文介绍了如何捕获std :: unique_ptr“by move”对于std :: for_each中的lambda的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习c ++ 11中的新功能,遇到了这个问题。我想捕获一个unique_ptr通过移动它在lambda内作为for_each的参数。

I am learning the new features in c++11 and came across this problem. I'd like to capture an unique_ptr by moving it inside a lambda as an argument for for_each.

设置:

std::array<int,4> arr = {1,3,5,6};
std::unique_ptr<int> p(new int);  (*p) = 3;

尝试1 - 不工作,因为unique_ptr没有复制构造函数。 c ++ 0x不指定通过移动语法。

attempt 1 - doesn't work because unique_ptr doesn't have a copy constructor. c++0x doesn't specify the pass by move syntax.

std::for_each(arr.begin(), arr.end(), [p](int& i) { i+=*p; });

尝试2 - 使用bind将移动的p的副本绑定到需要int& / p>

attempt 2 - use bind to bind a moved copy of p to a function that takes int&:

std::for_each(arr.begin(), arr.end(),
     std::bind([](const unique_ptr<int>& p, int& i){
          i += (*p);
     }, std::move(p))
);

编译器声称'result':symbol既不是类模板,函数模板。

本练习的主要目的是了解如何捕获可移动变量并将其缓存以供以后使用。 / p>

The main purpose of the exercise is to understand how a movable variable be captured in a lambda that's cached for later use.

推荐答案

您不能以任何直接的方式将可移动变量捕获到lambda中。

You cannot capture a movable variable into a lambda in any straightforward way.

Lambdas通过复制或参考捕捉。因此,要捕获只移动变量,您必须将其包装在一个对象中,其中复制=>移动(例如 std :: auto_ptr )。这是一个讨厌的黑客。

Lambdas capture by copy or by reference. Thus, to capture a move-only variable, you have to wrap it in an object where copying => moving (such as std::auto_ptr). This is a nasty hack.

在你的例子中,你可以通过引用捕获,但如果这只是简化的代码,它可能不会做你想要的真正的代码:

In your example, you can just capture by reference, but if this was just simplified code it may not do what you wanted with the real code:

std::for_each(arr.begin(), arr.end(), [&p](int& i) { i+=*p; });

这里是一个复制移动包装器:

Here's a copy-move-only wrapper:

template<typename T>
struct move_on_copy_wrapper
{
    mutable T value;

    move_on_copy_wrapper(T&& t):
        value(std::move(t))
    {}

    move_on_copy_wrapper(move_on_copy_wrapper const& other):
        value(std::move(other.value))
    {}

    move_on_copy_wrapper(move_on_copy_wrapper&& other):
        value(std::move(other.value))
    {}

    move_on_copy_wrapper& operator=(move_on_copy_wrapper const& other)
    {
        value=std::move(other.value);
        return *this;
    }

    move_on_copy_wrapper& operator=(move_on_copy_wrapper&& other)
    {
        value=std::move(other.value);
        return *this;
    }

};

您可以这样使用:

int main()
{
    std::unique_ptr<int> p(new int(3));
    move_on_copy_wrapper<std::unique_ptr<int>> mp(std::move(p));

    [mp]()
    {
        std::cout<<"*mp.value="<<*mp.value<<std::endl;
    }
    ();

    std::cout<<"p="<<p.get()<<", mp="<<mp.value.get()<<std::endl;
}

这篇关于如何捕获std :: unique_ptr“by move”对于std :: for_each中的lambda的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆