Std::bind和unique_ptr语言 - 如何移动
std::bind and unique_ptr - how to move only?
我必须通过低级系统例程调用函数,该例程获得传递的函数和参数。
void doLater(void* func, void* arg);
我想用bind调用任何函数和参数的callLater函数。所以:
template<typename Call>
void caller(void *arg) {
std::unique_ptr<Call> upCall(static_cast<Call*>(arg));
(*upCall)();
}
template<class Function, class... Args>
void callLater(Function &&f, Args&&...args) {
typedef decltype(std::bind(std::forward<Function>(f), std::forward<Args>(args)...))) Call;
Call* call = new Call(std::bind(std::forward<Function>(f), std::forward<Args>(args)...));
doLater(caller<Call>, (void*) call);
}
与std::unique_ptr一起使用会产生不需要的副本,因此无法编译。
std::function<void(std::unique_ptr<int>)> foo = [](std::unique_ptr<int> i) {
std::cout << "Hello world!n";
};
std::unique_ptr<int> value = std::make_unique<int>(1);
callLater(foo, std::move(value));
使用删除功能的std:: unique_ptr<_Tp _Dp>:: unique_ptr…
一个可能的解决方法是使用std::__bind_simple,就像在std::thread (gcc)中使用的那样,但它不是标准化的。你知道怎么解决这个问题吗?
生活例子。
这是一个概念的证明,你可能会把它添加到你正在寻找的表单中。
arg
parameter to callLater
:
首先,callLater
将参数作为void*
,所以你需要传递一个指向它的指针。
std::function
,然后将其地址传递为arg
因为你只能传递1个参数,而且这个参数必须是指向std::function
的指针,所以你必须绑定所有你想传递给std::function
调用的函数的参数。
因此,std::function
的格式必须为std::function<void()>
。
std::function<void()>* fn = new std::function<void()>;
// have to bind all arguments here
*fn = std::bind(func, i, d);
func
parameter to callLater
:
对于传递给callLater
的函数void*
,它必须是一个自由函数,将void* arg
强制转换为std::function
指针,然后解引用该指针以调用其operator()()
void arg_to_func(void* arg)
{
std::unique_ptr<std::function<void()>> fn(reinterpret_cast<std::function<void()>*>(arg));
(*fn)();
}
工作的例子:下面是一个绑定函数和lambda的工作示例:
#include <iostream>
#include <functional>
#include <memory>
void callLater(void* f, void* arg)
{
using fp = void(*)(void*);
fp func = (fp)f;
(*func)(arg);
}
using Call = std::function<void()>;
void arg_to_func(void* arg)
{
std::unique_ptr<Call> fn(reinterpret_cast<Call*>(arg));
(*fn)();
}
void func(int i, double d)
{
std::cout << "func " << i << ' ' << d << 'n';
}
int main()
{
// arguments we're going to capture
int i = 5;
double d = 2.3;
Call* fn;
// using std::bind to capture the variables
fn = new Call;
*fn = std::bind(func, i, d);
callLater((void*)arg_to_func, fn);
// using a lambda to capture the variables
fn = new Call;
*fn = [=](){ std::cout << "lambda " << i << ' ' << d << 'n'; };
callLater((void*)arg_to_func, fn);
return 0;
}
输出:func 5 2.3
lambda 5 2.3
相关文章:
- 将对象移动到std::shared_ptr
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- C / C++ 移位/偏移/向左或向右移动位图?
- MSVC将仅移动结构参数解释为指针
- 自定义先决条件对移动分配运算符有效吗
- 返回值优化:显式移动还是隐式
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 可以使用移动语义更改或改进此C++代码吗?
- 使lambda不可复制/不可移动
- c++在使用指针时移动语义
- 将QGraphicsItem的移动区域限制在多边形区域内
- SendInput()鼠标移动计算
- 按值 C++ 返回时进行双倍移动
- 移动二维数组中的字符
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- 平台独立性:它与将源代码从一个操作系统移动到另一个操作系统有何不同
- C++11编译器何时会使RVO和NRVO优于移动语义和常量引用绑定