我正在尝试创建std::function一个移动捕获lambda表达式.请注意,我可以创建一个移动捕获lambda表达式而不会出现问题; 只有当我尝试将其包装成一个std::function我得到错误时.
例如:
auto pi = std::make_unique<int>(0);
// no problems here!
auto foo = [q = std::move(pi)] {
*q = 5;
std::cout << *q << std::endl;
};
// All of the attempts below yield:
// "Call to implicitly-deleted copy constructor of '<lambda...."
std::function<void()> bar = foo;
std::function<void()> bar{foo};
std::function<void()> bar{std::move(foo)};
std::function<void()> bar = std::move(foo);
std::function<void()> bar{std::forward<std::function<void()>>(foo)};
std::function<void()> bar = std::forward<std::function<void()>>(foo);
Run Code Online (Sandbox Code Playgroud)
我会解释为什么我要写这样的东西.我写了一个UI库,类似于jQuery的或JavaFX的,允许用户通过传递给处理鼠标/键盘事件std::functions到方法有相似的名字on_mouse_down(),on_mouse_drag(),push_undo_action(),等.
显然,std::function我想要传入的理想情况下应该使用移动捕获lambda表达式,否则我需要求助于我在C++ 11作为标准时使用的丑陋的"release/acquire-in-lambda"习语:
std::function<void()> baz = …Run Code Online (Sandbox Code Playgroud) 类型擦除 - 你怎么称呼它?
如何boost::shared_ptr存储其删除器以及如何boost::function存储其功能对象?
有没有教授这个技巧的教程?
使用类型擦除函数对象的运行时成本是多少?
我想在C++ 11中的向量或其他容器中存储回调.
一种方法是存储std :: function的向量.这适用于具有可复制参数的lambda或std :: bind.
但是,如果存在一个不可复制(仅可移动)参数,则由于从lambda/std :: bind内部类型到std :: function的转换,它将失败...
#include <vector>
class NonCopyable {
public:
NonCopyable() = default;
NonCopyable(const NonCopyable &) = delete;
NonCopyable(NonCopyable &&) = default;
};
int main() {
std::vector<std::function<void()>> callbacks;
callbacks.emplace_back([] {});
NonCopyable tmp;
callbacks.emplace_back(std::bind([](const NonCopyable &) {}, std::move(tmp)));
// When converting the object returned by std::bind to a std::function,
// a copy of the arguments happen so this code cannot compile.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法将std :: bind参数移动到std :: function而不是复制它们?
我有一个函数,它使用move-capture构造一个lambda函数(仅限C++ 1y)并返回它.
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
function<int ()> makeLambda(unique_ptr<int> ptr) {
return [ ptr( move(ptr) ) ] () {
return *ptr;
};
}
int main() {
// Works
{
unique_ptr<int> ptr( new int(10) );
auto function1 = [ ptr(move(ptr)) ] {
return *ptr;
};
}
// Does not work
{
unique_ptr<int> ptr( new int(10) );
auto function2 = makeLambda( std::move(ptr) );
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然而,似乎在返回时,unique_ptr<int>调用了复制构造函数.为什么这个/我怎么能绕过这个?