C++ 如何为无法改变其指向值的非常量对象创建std::experimental::observer_ptr?

C++ 如何为无法改变其指向值的非常量对象创建std::experimental::observer_ptr?,c++,constants,smart-pointers,c++-standard-library,c++-ts,C++,Constants,Smart Pointers,C++ Standard Library,C++ Ts,这是创建一个非const对象的std::experimental::observative::observer_ptr的标准方法吗,该对象不能改变它所指向的值 autoi=int{0}; 自动p=std::experimental::make_observer(&std::as_const(i)); *p=1;//编译错误,如所需 编辑: 如果指针已经存在(我认为这是更常见的用例),该怎么办?我们需要const\u cast吗 autoi=int{0}; 自动p=&i; 自动q=std::实

这是创建一个非
const
对象的
std::experimental::observative::observer_ptr
的标准方法吗,该对象不能改变它所指向的值

autoi=int{0};
自动p=std::experimental::make_observer(&std::as_const(i));
*p=1;//编译错误,如所需

编辑:

如果指针已经存在(我认为这是更常见的用例),该怎么办?我们需要
const\u cast

autoi=int{0};
自动p=&i;
自动q=std::实验::生成观察者(const_cast(p));
*q=1;//编译错误,如所需

不要把事情复杂化。照办

observer_ptr<const int> p{&i};
但GCC和Clang似乎与规范有所不同。实现为
(element_type*)
构造函数使用限定名,因此阻止类模板参数推导


与std::make_pair非常相似,
make_observer
的存在是因为库基础知识2 TS是在C++17之前的时代创建的。类模板参数推断在那个时候不是一件事。如今,我们很少需要像
std::make_pair
(反例:参考包装器,请参阅)这样的单独make函数,同样,我们也很少需要
make_observer


因此,谈论使用C++17之前的特性(如C++17中的
observer\u ptr
)的“规范”方式没有多大意义。当然,如果类模板参数推断确实有效,我们可以使用它。在这两种情况下,
i
都不是一个“常量对象”。@nicolas Sure,但是可以推断,我指的是指向一个对象的指针,它不能改变它所指向的值。@Nicolas为了清楚起见,我编辑了原始问题。这可能是不使用
auto
make\u observer
的情况,但是,只是写出<代码> STD::实验::ObServyPPTR P<代码>,C++是否有标准的做事方式?由于运算符&有时可能会被重载,因此您可能还需要编写类似于
autop{::std::experimental::make_observer(::std::addressof(::std::as_const(i))}
在STL中不与智能指针构造助手一起使用CTAD(
std::make_unique
std::make_shared
)是一个很难打破的习惯,也是本例中混乱的根源。你说得对,在构建像
std::observer\u ptr
这样的“哑”智能指针时,不需要助手。如果你强调
std::observer\u ptr
和现有智能指针之间的区别,我会很高兴地接受你的回答,因为它与CTAD和
std::make\uptr
助手有关。@invexed我不认为这与智能/哑指针有很大关系。智能指针禁用CTAD的原因是没有很好的方法来区分从new和new[]获得的指针,并且使_共享一次
observer_ptr
基于C++14,所以我想在它上面谈论CTAD没有多大意义?在
observer_ptr
和其他智能指针之间仍然有区别,因为前者可以使用CTAD,但后者不能(这就引出了我的问题)。不过我会接受你的回答;如果需要,人们可以阅读这些评论。谢谢。@invexed
observer\u ptr
不在标准中,因此没有针对C++17进行更新。。。
observer_ptr p{&std::as_const(i)};