如何捕获一个unique_ptr到lambda表达式? [英] How to capture a unique_ptr into a lambda expression?
问题描述
我尝试过以下操作:
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屋!