将"std::move(*this)"放入从"this->some_method"创建的对象中是否安全?
Is it safe to `std::move(*this)` into an object being created from `this->some_method`?
我试图建立一个可调用的对象链,可以稍后异步执行。我想尝试以下方法:构建一个节点的"嵌套"结构(通过将每个节点移动到它的"父节点"中),从而产生一个存储所有计算的对象,并且可以根据需要启动链。
这就是我的想法:
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
为可移动可调用对象,是否安全?
node::then
时调用std::move(*this)
你可以这么做,而且很安全。它只会使成员处于未定义但有效的状态在大多数情况下。话虽如此,移动this
是安全的,只要你不试图再次使用它的成员。但是对于标准库类型和大多数用户定义的类型,这甚至都不是问题。
有一件事我要改变。我只允许从右值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)
};
}
代码中是否存在问题取决于该代码如何处理它所获得的引用。如果被调用的代码将对象转换成糊状,那么当它返回时,您的代码必须处理已转换成糊状的对象。但是对于任何从成员函数中调用的函数都是如此,无论它是使用右值引用、可修改的左值引用、指针还是您可能想到的任何其他机制调用。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 使用std::multimap迭代器创建std::list
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 使用CMake创建QML插件
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 试图在visual studio上用C++创建一个桌面应用程序
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 如何在C++20中创建模板别名的推导指南
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 如何创建一个空的全局类并在启动时实例化它
- 无法创建抽象类的实例
- 链接到自行创建的dll失败
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++类内存结构中创建"spacer"?
- 终端不会为C++文件创建.exe文件吗
- 如何在 c++ 中创建 map<string, class::method>