如何从C ++ 14中的广义lambda捕获返回包含std :: unique_ptr的std :: function? [英] How to return a std::function that contains a std::unique_ptr from a generalized lambda capture in C++14?
问题描述
我们如何从广义lambda捕获中返回包含 std :: unique_ptr
的 std :: function
在C ++ 14中?具体来说,在以下代码中
How do we return a std::function
that contains a std::unique_ptr
from a generalized lambda capture in C++14? Specifically, in the following code
// For std::function
#include <functional>
// For std::iostream
#include <iostream>
// For std::unique_ptr
#include <memory>
#if 0
std::function <void()> make_foo() {
auto x = std::make_unique <int> (3);
return [x=std::move(x)]() {
std::cout << *x << std::endl;
};
}
#endif
int main() {
auto x = std::make_unique <int> (3);
auto foo = [x=std::move(x)]() {
std::cout << *x << std::endl;
};
foo();
}
在GCC 4.9.2和C ++ 14上运行时,一切正常上。具体来说,它表明广义lambda捕获了工作。但是,当我们更改 #if 1
的代码时,会出现编译错误:
Everything works fine when run with GCC 4.9.2 and C++14 turned on. Specifically, it shows that generalized lambda captures work. However, when we change the code where #if 1
, we get the compile error:
g++ -g -std=c++14 test01.cpp -o test01
In file included from test01.cpp:4:0:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/include/g++-v4/functional: In instantiation of 'static void std::_Function_base::_Base_manager<_Functor>::_M_clone(std::_Any_data&, const std::_Any_data&, std::false_type) [with _Functor = make_foo()::<lambda()>; std::false_type = std::integral_constant<bool, false>]':
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/include/g++-v4/functional:1914:51: required from 'static bool std::_Function_base::_Base_manager<_Functor>::_M_manager(std::_Any_data&, const std::_Any_data&, std::_Manager_operation) [with _Functor = make_foo()::<lambda()>]'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/include/g++-v4/functional:2428:19: required from 'std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = make_foo()::<lambda()>; <template-parameter-2-2> = void; _Res = void; _ArgTypes = {}]'
test01.cpp:17:5: required from here
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/include/g++-v4/functional:1878:34: error: use of deleted function 'make_foo()::<lambda()>::<lambda>(const make_foo()::<lambda()>&)'
__dest._M_access<_Functor*>() =
^
test01.cpp:15:27: note: 'make_foo()::<lambda()>::<lambda>(const make_foo()::<lambda()>&)' is implicitly deleted because the default definition would be ill-formed:
return [x=std::move(x)]() {
^
test01.cpp:15:27: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]'
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/include/g++-v4/memory:81:0,
from test01.cpp:10:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.2/include/g++-v4/bits/unique_ptr.h:356:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
^
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 1
现在,鉴于我们要返回的函数包含 std :: unique_ptr
,因此我们可以t复制生成的 std :: function
。但是,由于我们要返回的是即时创建的lambda函数,因此这不是r值并且定义有效吗?基本上,有什么方法可以修复 make_foo
,在那里我们仍然可以获取 std :: unique_ptr
的广义lambda捕获?
Now, given that the function we're returning contains a std::unique_ptr
, it makes sense that we can't copy the resulting std::function
. However, since we're returning a lambda function created on the fly, shouldn't this be an r-value and the definition valid? Basically, is there any way to fix make_foo
where we still have a generalized lambda capture of a std::unique_ptr
?
推荐答案
为@TC在评论中说, std :: function
需要它包装为CopyConstructible,而您的lambda并不是因为 unique_ptr
数据成员。
As @T.C. says in the comments, std::function
requires that the callable it wraps be CopyConstructible, and your lambda isn't because of the unique_ptr
data member.
C ++ 14的函数的返回类型推导的说明,该函数从 make_foo
返回lambda并避免将其包装在 std :: function
。
You can make use of C++14's return type deduction for functions to return the lambda from make_foo
and avoid wrapping it in std::function
.
auto make_foo() {
auto x = std::make_unique <int> (3);
return [x=std::move(x)]() {
std::cout << *x << std::endl;
};
}
make_foo()(); // prints 3
这篇关于如何从C ++ 14中的广义lambda捕获返回包含std :: unique_ptr的std :: function?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!