This answer解释了如何在C ++ 14中移动捕获lambda中的变量。
但是一旦你在lambda中移动捕获了一个不可复制的对象(例如std::unique_ptr
),你就无法复制lambda本身。
如果您可以移动 lambda,那就没问题了,但是在尝试这样做时我遇到了编译错误:
using namespace std;
class HasCallback
{
public:
void setCallback(std::function<void(void)>&& f)
{
callback = move(f);
}
std::function<void(void)> callback;
};
int main()
{
auto uniq = make_unique<std::string>("Blah blah blah");
HasCallback hc;
hc.setCallback(
[uniq = move(uniq)](void)
{
std::cout << *uniq << std::endl;
});
hc.callback();
}
这会导致g++
出现以下错误(我试图仅复制相关行):
error: use of deleted function ‘main()::<lambda()>::<lambda>(const main()::<lambda()>&’
......我想,我暗示我移动lambda的尝试失败了。
clang++
给出了类似的错误。
我明确地尝试了move
lambda(即使它是一个临时值),但这没有帮助。
编辑:以下答案充分解决了上述代码产生的编译错误。对于替代方法,只需将release
唯一指针的目标值std::shared_ptr
转换为unique_ptr
,即可复制 。 (我不是写这个作为答案,因为这会假设这是一个XY问题,但是std::function
无法在转换为auto_ptr
的lambda中使用的根本原因理解很重要。)
编辑2:非常滑稽,我只是意识到unique_ptr
实际上会在这里做正确的事(!),据我所知。它的行为基本上类似于angular.module("myApp")
.factory("utentiService", function($http) {
return {
getData: function () {
return $http.get("backListaUtenti.php").then(function (response) {
return response.data;
});
}
};
});
angular.module("myApp")
.controller("utenteCtrl", function($scope, $routeParams, utentiService, filterFilter) {
var userId = $routeParams.userId;
utentiService.getData().then(function(data) {
$scope.utente = filterFilter(data, { id: userId })[0];
});
});
angular.module("myApp")
.controller("listaUtentiCtrl", function($scope, utentiService) {
utentiService.getData().then(function (data) {
$scope.utenti = data;
});
});
,但允许复制构造代替移动构造。
答案 0 :(得分:16)
你可以移动 lambda ,没关系。这不是你的问题,你试图用不可复制的lambda实例化std::function
。而且:
template< class F >
function( F f );
<{3}}的构造函数确实:
5)使用
f
的副本初始化目标。
这是因为function
:
满足CopyConstructible和CopyAssignable的要求。
由于function
必须是可复制的,因此您放入其中的所有内容也必须是可复制的。并且只有移动的lambda不符合该要求。
答案 1 :(得分:12)
std::function
不是lambda!它是一个包装器,可以从任何类型的可调用构造,包括lambda。 std::function
需要callable be copy-constructible,这就是您的示例失败的原因。
可以再次移动仅移动的lambda,如下所示。
template<typename F>
void call(F&& f)
{
auto f1 = std::forward<F>(f); // construct a local copy
f1();
}
int main()
{
auto uniq = make_unique<std::string>("Blah blah blah");
auto lambda = [uniq = move(uniq)]() {
std::cout << *uniq << std::endl;
};
// call(lambda); // doesn't compile because the lambda cannot be copied
call(std::move(lambda));
}