I am having trouble with std::bind
and using a moveable type as a parameter. Is read this and this, but in those cases I actually see the issue since there the OP want's to have a rvalue reference inside the bind. What I want to is have a lvalue, but just to move-construct it when calling std::bind
. Here is a minimal sample:
#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;
}
So I want Param
to be move constructible - as shown in the comments adding a copy ctor solves everything (and if everything else fails I will just go that way). The only thing that from my point of view could prohibit this is if the result of std::bind
must be copy constructible, but cppreference states:
The return type of std::bind is CopyConstructible if all of its member objects (specified above) are CopyConstructible, and is MoveConstructible otherwise.
I thought that if the type how the variable is stored in the bind is deduced from the call then std::move
could cause an attempt to store a rvalue reference, thus the second call where I explicitly state the template parameters (and would expect the bind itself to have a member of type Param
which is move constructible and move assignable).
What am I missing here?
Aucun commentaire:
Enregistrer un commentaire