std::vector 个只能移动的 lambda,这可能吗?
std::vector of movable-only lambdas, is it possible?
我想要一个 lambda 集合,要求 lambda 不能被复制,只能被移动。
这是因为 lambas 可能需要移动捕获他们的一些不可复制构造的参数。
示例:
NonCopyableType varName ;
auto func = [a=move(varName)](){ ... } ; //varName is move-captured
在此之后我想将 func
存储在 vector
中,但我不能使用 std::function
类型,因为它要求 lambdas 是可复制的。
vector<function<void()>> list ;
list.push_back(func) ; //won't work
是否可以用其他方式做到这一点?
当然可以。只需编写您自己的 function
克隆,该克隆只能移动。这是一个仅支持 nullary callables 的简化版本,但您可以看到如何扩展它:
class move_function
{
struct placeholder {
virtual ~placeholder() = default;
virtual void call() = 0;
};
template <class T>
struct holder : placeholder {
T f;
void call() override { f(); }
};
std::unique_ptr<placeholder> f_;
public:
template <class F,
class R = std::result_of_t<F&()>,
std::enable_if_t<!std::convertible<std::decay_t<F>*, move_function*>::value, int> = 0>
move_function(F&& f)
: f_(new std::decay_t<F>{std::forward<F>(f)})
{ }
void operator()() const { f_->call(); }
};
所有隐式定义的特殊成员函数已经为我们做了正确的事情。
我想要一个 lambda 集合,要求 lambda 不能被复制,只能被移动。
这是因为 lambas 可能需要移动捕获他们的一些不可复制构造的参数。
示例:
NonCopyableType varName ;
auto func = [a=move(varName)](){ ... } ; //varName is move-captured
在此之后我想将 func
存储在 vector
中,但我不能使用 std::function
类型,因为它要求 lambdas 是可复制的。
vector<function<void()>> list ;
list.push_back(func) ; //won't work
是否可以用其他方式做到这一点?
当然可以。只需编写您自己的 function
克隆,该克隆只能移动。这是一个仅支持 nullary callables 的简化版本,但您可以看到如何扩展它:
class move_function
{
struct placeholder {
virtual ~placeholder() = default;
virtual void call() = 0;
};
template <class T>
struct holder : placeholder {
T f;
void call() override { f(); }
};
std::unique_ptr<placeholder> f_;
public:
template <class F,
class R = std::result_of_t<F&()>,
std::enable_if_t<!std::convertible<std::decay_t<F>*, move_function*>::value, int> = 0>
move_function(F&& f)
: f_(new std::decay_t<F>{std::forward<F>(f)})
{ }
void operator()() const { f_->call(); }
};
所有隐式定义的特殊成员函数已经为我们做了正确的事情。