你应该如何为一个不能改变它指向的值的非常量对象创建一个 std::experimental::observer_ptr ?

How should you create a std::experimental::observer_ptr to a non-const object that cannot mutate the value it points to?

这是为无法改变其指向的值的非const对象创建std::experimental::observer_ptr的规范方法吗?

auto i = int{0};

auto p = std::experimental::make_observer(&std::as_const(i));
*p = 1; // compilation error, as desired

https://godbolt.org/z/h3Uq0o

编辑:

如果指针已经存在怎么办(我想这是更常见的用例)?我们必须 const_cast 吗?

auto i = int{0};
auto p = &i;

auto q = std::experimental::make_observer(const_cast<const int*>(p));
*q = 1; // compilation error, as desired

https://godbolt.org/z/NbR6Nj

不要把事情复杂化。就这样

observer_ptr<const int> p{&i};

一切都很好。

你也可以按照spec:

observer_ptr p{&std::as_const(i)};

但 GCC 和 Clang 似乎与此处的规范有所不同。该实现为 (element_type*) 构造函数使用了限定名称,因此阻止了 class 模板参数推导。


很像 std::make_pairmake_observer 的存在是因为库基础 2 TS 是在 C++17 之前的时代创建的。 Class 模板参数推导在那个时候还不算什么。现在,我们很少需要像std::make_pair这样单独的make函数(反例:引用包装器,参见),同样我们也很少需要make_observer.

因此,谈论使用 C++17 中的 observer_ptr 等 C++17 之前的功能的 "canonical" 方式没有多大意义。当然,如果确实有效,我们可以使用 class 模板参数推导。 observer_ptr.

的设计根本就没有考虑到这一点