【发布时间】:2020-03-30 09:46:32
【问题描述】:
我在使用std::bind 并使用可移动类型作为参数时遇到问题。读取this 和this,但在这些情况下,我实际上看到了问题,因为OP 希望在绑定中有一个右值引用。我想要的是有一个左值,但只是在调用std::bind 时移动构造它。这是一个最小的示例:
#include <functional>
struct Foo
{
using Callback = std::function<void(int)>;
void Do(const Callback &callback)
{
callback(5);
}
};
class Param
{
private:
Param() {};
public:
Param(Param&&)
{
}
// commenting out copy ctor triggers the last two invocations in Bar() to fail
#if 1
Param(const Param&)
{
}
#endif
Param& operator=(Param&&)
{
return *this;
}
static Param Create()
{
return Param();
}
int value_ = 10;
};
struct Bar
{
Bar()
{
Foo f;
f.Do(std::bind(&Bar::Callback1, this, std::placeholders::_1));
Param p(Param::Create());
f.Do(std::bind(&Bar::Callback2, this, std::move(p), std::placeholders::_1)); // does not work w/o copy ctor
f.Do(std::bind<decltype(&Bar::Callback2), Bar*, Param>(&Bar::Callback2, this, std::move(p), std::placeholders::_1)); // does not work w/o copy ctor
}
void Callback1(int a)
{
printf("%d\n", a);
}
void Callback2(const Param &p, int a)
{
printf("%d %d\n", a, p.value_);
}
};
int main()
{
Bar b;
}
所以我希望 Param 可以移动构造 - 如 cmets 所示,添加一个复制 ctor 可以解决所有问题(如果其他所有问题都失败了,我会这样做)。在我看来,唯一可以禁止的是 std::bind 的结果必须是可复制构造的,但 cppreference 声明:
如果 std::bind 的所有成员对象(上面指定)都是 CopyConstructible,则返回类型是 CopyConstructible,否则是 MoveConstructible。
我认为如果从调用中推断出变量在绑定中的存储类型,那么std::move 可能会导致尝试存储右值引用,因此我在第二次调用中明确声明了模板参数(并且会期望绑定本身具有 Param 类型的成员,该成员可移动构造和移动分配)。
我在这里错过了什么?
【问题讨论】:
标签: c++11