首页 > 解决方案 > 为什么右值 unique_ptr 的 operator* 返回左值?

问题描述

从“死”的 unique_ptr 使用 operator* 的返回值是不好的。

以下代码可以编译,但当然会导致未定义行为:

auto& ref = *std::make_unique<int>(7);
std::cout << ref << std::endl;

为什么标准没有将 std::unique_ptr值的 operator* 返回类型设为内部值的右值,而不是左值,如下所示:

// could have been done inside unique_ptr
T& operator*() & { return *ptr; }
T&& operator*() && { return std::move(*ptr); }

在这种情况下,这可以正常工作:

std::cout << *std::make_unique<int>(7) << std::endl;

但是一开始的代码不会编译(不能将右值绑定到左值)。


旁注:当然有人仍然可以编写像下面这样的错误代码,但它更冗长地说“我是 UB”,恕我直言,因此与此讨论不太相关:

auto&& ref = *std::make_unique<int>(7);
std::cout << ref << std::endl;

std::unique_ptr 的右值上的 operator* 是否有充分的理由返回左值引用?

标签: c++c++11undefined-behaviorunique-ptrrvalue-reference

解决方案


就所涉及的值类别和基本思想而言,您的代码相当于:

auto &ref = *(new int(7));

new int(7)产生一个指针对象,它是一个纯右值表达式。取消引用该纯右值会产生一个左值表达式。

无论指针对象是右值还是左值,应用于*指针都会产生左值。这不应该仅仅因为指针是“智能的”而改变。


推荐阅读