我正在尝试构建一个可以在以后异步执行的可调用对象链。我想尝试以下方法:构建节点的“嵌套”结构(通过将每个节点 move 到其“父节点”) 产生一个存储所有计算并可以启动链的对象按需。
这是我的想法:
template <typename TParent, typename TF>
struct node
{
TParent _parent;
TF _f;
node(TParent&& parent, TF&& f)
: _parent{std::move(parent)}, _f{std::move(f)}
{
}
template <typename TFContinuation>
auto then(TFContinuation&& f_continuation)
{
using this_type = node<TParent, TF>;
return node<this_type, std::decay_t<TFContinuation>>
{std::move(*this), std::move(f_continuation)};
// ^^^^^^^^^^^^^^^^
// ...safe?
}
};
上面的代码将允许用户编写如下所示的链:
int main()
{
node n{some_root_callable, []{/*...*/}};
n.then([]{/*...*/})
.then([]{/*...*/})
.then([]{/*...*/})
.then([]{/*...*/});
}
(真正的实现将支持更有用的抽象,例如 when_all(...)
或 when_any(...)
。)
假设 TParent
、TF
和 TFContinuation
是可 move 的可调用对象,它安全吗(即好- defined) 在 node::then
调用期间调用 std::move(*this)
?
最佳答案
你可以这样做而且很安全。在大多数情况下,它只会让成员处于未定义但有效的状态。话虽如此, move this
是安全的,只要您不再尝试使用它的成员。但是对于标准库类型和大多数用户定义的类型,这甚至都不是问题。
有一件事我会改变。我只允许从右值调用:
template <typename TFContinuation> // v-- notice the && here.
auto then(TFContinuation&& f_continuation) && {
using this_type = node<TParent, TF>;
return node<this_type, std::decay_t<TFContinuation>>{
std::move(*this), std::move(f_continuation)
};
}
很棒的是当它不是右值时你甚至可以重载它:
template <typename TFContinuation>
auto then(TFContinuation&& f_continuation) const & {
using this_type = node<TParent, TF>;
return node<this_type, std::decay_t<TFContinuation>>{
*this, std::move(f_continuation)
};
}
关于c++ - 将 `std::move(*this)` 放入从 `this->some_method` 创建的对象中是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40616296/