你应该如何为一个不能改变它指向的值的非常量对象创建一个 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
编辑:
如果指针已经存在怎么办(我想这是更常见的用例)?我们必须 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
不要把事情复杂化。就这样
observer_ptr<const int> p{&i};
一切都很好。
你也可以按照spec:
observer_ptr p{&std::as_const(i)};
但 GCC 和 Clang 似乎与此处的规范有所不同。该实现为 (element_type*)
构造函数使用了限定名称,因此阻止了 class 模板参数推导。
很像 std::make_pair
,make_observer
的存在是因为库基础 2 TS 是在 C++17 之前的时代创建的。 Class 模板参数推导在那个时候还不算什么。现在,我们很少需要像std::make_pair
这样单独的make函数(反例:引用包装器,参见),同样我们也很少需要make_observer
.
因此,谈论使用 C++17 中的 observer_ptr
等 C++17 之前的功能的 "canonical" 方式没有多大意义。当然,如果确实有效,我们可以使用 class 模板参数推导。 observer_ptr
.
的设计根本就没有考虑到这一点
这是为无法改变其指向的值的非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
编辑:
如果指针已经存在怎么办(我想这是更常见的用例)?我们必须 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
不要把事情复杂化。就这样
observer_ptr<const int> p{&i};
一切都很好。
你也可以按照spec:
observer_ptr p{&std::as_const(i)};
但 GCC 和 Clang 似乎与此处的规范有所不同。该实现为 (element_type*)
构造函数使用了限定名称,因此阻止了 class 模板参数推导。
很像 std::make_pair
,make_observer
的存在是因为库基础 2 TS 是在 C++17 之前的时代创建的。 Class 模板参数推导在那个时候还不算什么。现在,我们很少需要像std::make_pair
这样单独的make函数(反例:引用包装器,参见make_observer
.
因此,谈论使用 C++17 中的 observer_ptr
等 C++17 之前的功能的 "canonical" 方式没有多大意义。当然,如果确实有效,我们可以使用 class 模板参数推导。 observer_ptr
.