c++ - 使用 operator() 从代理类返回 unique_ptr 成员变量
问题描述
我想做一个包装类(在这种情况下是一个非空检查,但它可能是其他检查)。
有什么方法可以通过operator()
它来提取成员变量,从而可以移出成员变量。用例是一个std::unique_ptr<>
这是用例
#include <memory>
struct S {
int x = 0;
S(int x): x(x) {}
};
template <typename Type>
class NotNull
{
public:
NotNull(Type value): m_value(std::move(value)) {}
operator Type&() // <--------------------------------- this is the question
{
assertIsNotNull();
return m_value;
}
typename std::pointer_traits<Type>::element_type *get() {
return m_value.get();
}
private:
void assertIsNotNull() {}
Type m_value;
};
这就是需要工作的
// Test code
int main() {
{
NotNull<S *> x {new S{10}};
auto y = x; // This works
delete y;
}
{
NotNull<std::shared_ptr<S>> x{std::make_shared<S>(10)};
auto y = x; // This works
}
{
NotNull<std::unique_ptr<S>> x{std::make_unique<S>(10)};
S* y = x.get(); // This does work, and needs to work as expected
// that is _not_ move the member
}
{
NotNull<std::unique_ptr<S>> x{std::make_unique<S>(10)};
auto y = std::move(x); // This copies the whole class
}
{
NotNull<std::unique_ptr<S>> x{std::make_unique<S>(10)};
std::unique_ptr<S> y = std::move(x); // <----------------- This does not work
}
}
编译器似乎不明白我想在 std::move 调用中转换为 unique_ptr 。
error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = S; _Dp = std::default_delete<S>]'
57 | std::unique_ptr<S> y = std::move(x);
|
是否可以以某种方式使用类作为 std::unique_ptr 的代理并获得这种用于移出成员变量的语法。
PS。正如您可能已经猜到的那样,我不能依赖例如 gsl::not_null,因为据我所知,该功能不存在。DS。
解决方案
编译器知道你想转换成一个 unique_ptr&(即 Type&)就好了。当您将该转换的结果分配给本地 unique_ptr 对象时会出现问题:由于它是左值引用,编译器会尝试调用复制构造函数(而不是移动构造函数,它需要右值引用),但是由于 unique_ptr 删除了它的副本构造函数,你得到错误。
您可能想要在该行中执行的操作是转换为 unique_ptr&& (即右值引用)。为此,您可以基于ref-qualifiers重载转换运算符:
operator Type&() & // converts to lvalue ref if invoked on lvalue
{
assertIsNotNull();
return m_value;
}
operator Type&&() && // converts to rvalue ref if invoked on a temporary
{
assertIsNotNull();
return std::move(m_value);
}
这样,转换运算符将转换为调用它的相同类型的引用(即,从普通变量中使用的左值,如果在临时或移动对象上使用,则为右值)。
推荐阅读
- python - 如何处理 FutureWarning:Int64Index.flags 已弃用,将在未来版本中删除?
- python - 查找多页表中的页数
- node.js - 我无法理解这个 Node JS 方法是如何返回“任务列表”的?
- python - 一对一课程未在 django 中更新:给出完整性错误
- pandas - 熊猫数据框子图按列分组
- sql-server - 查询结果正确但使用执行标量函数系统返回 0
- image - 如何从任何消费产品的图像中检测文本/徽标细节?
- dart -
- firebase - 如何从 Firestore 获取过去一小时内更新的文档?
- javascript - 空手道 JavaScript 数组格式