Is this the canonical way to create a std::experimental::observer_ptr
to a non- const
object that cannot mutate the value it points to?
auto i = int{0};
auto p = std::experimental::make_observer(&std::as_const(i));
*p = 1; // compilation error, as desired
EDIT:
What if the pointer already exists (which I suppose is the more common use-case)? Would we have to 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
Don't complicate matters. Just do
observer_ptr<const int> p{&i};
And everything is fine.
You can also do this according to the spec :
observer_ptr p{&std::as_const(i)};
but GCC and Clang seems to diverge from the spec here. The implementation uses a qualified name for the (element_type*)
constructor, therefore blocking class template argument deduction.
Much like std::make_pair
, make_observer
exists because the library fundamentals 2 TS is created in pre-C++17 era. Class template argument deduction wasn't a thing at that time. Nowadays, we rarely need a separate make function like std::make_pair
(counterexample: reference wrappers, see Usefulness of std::make_pair
and std::make_tuple
in C++1z ), and similarly we rarely need make_observer
.
Therefore, it doesn't make much sense to talk about the "canonical" way of using a pre-C++17 feature like observer_ptr
in C++17. Granted, we can use class template argument deduction if it actually works. That's simply not even considered in the design of observer_ptr
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.