如何捕获一个unique_ptr到lambda表达式? [英] How to capture a unique_ptr into a lambda expression?

查看:570
本文介绍了如何捕获一个unique_ptr到lambda表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试过以下操作:

  std :: function< void()> getAction(std :: unique_ptr< MyClass>&& psomething){
//调用者赋予psomething的所有权
return [psomething](){
psomething-> do_some_thing ;
// psomething预计将在此点之后释放
};
}

但它不编译。任何想法?



更新:



根据建议,需要一些新的语法来明确指定我们需要转移对lambda的所有权,我现在考虑以下语法:

  std :: function< void()> getAction(std :: unique_ptr< MyClass> psomething){
//调用者赋予psomething的所有权
return [auto psomething = move(psomething)](){
psomething-> do_some_thing ();
// psomething预计将在此点之后释放
};
}

这将是一个很好的候选人吗?



UPDATE 1:



我将展示我的实现 move copy 如下:

  template< typename T> 
T copy(const T& t){
return t;
}

// process lvalue references
template< typename T>
T move(T& t){
return std :: move(t);
}

class A {/*...*/};

void test(A& a);

int main(int,char **){
A a;
test(copy(a)); // OK,copied
test(move(a)); // OK,moved
test(A()); // OK,临时对象
test(copy(A())); // OK,正在复制临时对象
//您可以通过让副本接受T&
// test(move(A()));你不应该移动一个临时对象
//这是不好的有一个右值版本的移动。
// test(a);禁止,你必须说天气你要复制或移动
//从一个左值引用。
}


解决方案

code> unique_ptr 中。事实上,如果你想永久捕获lambda中的任何东西,它必须可复制;



这可能被认为是C ++ 11中的一个缺陷,但是你需要一些语法来明确地说你想移动 unique_ptr 值插入lambda。 C ++ 11规范是非常谨慎的措词,以防止对命名变量的隐式移动;这就是为什么 std :: move 存在,这是一个的东西。



要做你想要的,需要使用 std :: bind (这将是半卷积的,需要一个短序列绑定)或只返回一个常规的旧对象。



此外,从不 unique_ptr c>&&&& ,除非你真正写它的移动构造函数。只是把它的价值;用户可以通过值提供它的唯一方法是使用 std :: move 。事实上,除非你正在编写移动构造函数/赋值运算符(或实现转发函数),否则不要采取任何&&& / p>

I have tried the following:

std::function<void ()> getAction(std::unique_ptr<MyClass> &&psomething){
    //The caller given ownership of psomething
    return [psomething](){ 
        psomething->do_some_thing();
        //psomething is expected to be released after this point
    };
}

But it does not compile. Any ideas?

UPDATE:

AS suggested, some new syntax is required to explicitly specify we need to transfer the ownership to the lambda, I am now thinking about the following syntax:

std::function<void ()> getAction(std::unique_ptr<MyClass> psomething){
    //The caller given ownership of psomething
    return [auto psomething=move(psomething)](){ 
        psomething->do_some_thing();
        //psomething is expected to be released after this point
    };
}

Would it be a good candidate?

UPDATE 1:

I will show my implementation of move and copy as following:

template<typename T>
T copy(const T &t) {
    return t;
}

//process lvalue references
template<typename T>
T move(T &t) {
    return std::move(t);
}

class A{/*...*/};

void test(A &&a);

int main(int, char **){
    A a;
    test(copy(a));    //OK, copied
    test(move(a));    //OK, moved
    test(A());        //OK, temporary object
    test(copy(A()));  //OK, copying temporary object
    //You can disable this behavior by letting copy accepts T &  
    //test(move(A())); You should never move a temporary object
    //It is not good to have a rvalue version of move.
    //test(a); forbidden, you have to say weather you want to copy or move
    //from a lvalue reference.
}

解决方案

You cannot permanently capture a unique_ptr in a lambda. Indeed, if you want to permanently capture anything in a lambda, it must be copyable; merely movable is insufficient.

This could be considered a defect in C++11, but you would need some syntax to explicitly say that you wanted to move the unique_ptr value into the lambda. The C++11 specification is very carefully worded to prevent implicit moves on named variables; that's why std::move exists, and this is a good thing.

To do what you want will require either using std::bind (which would be semi-convoluted, requiring a short sequence of binds) or just returning a regular old object.

Also, never take unique_ptr by &&, unless you are actually writing its move constructor. Just take it by value; the only way a user can provide it by value is with a std::move. Indeed, it's generally a good idea to never take anything by &&, unless you're writing the move constructor/assignment operator (or implementing a forwarding function).

这篇关于如何捕获一个unique_ptr到lambda表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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