Как вам создать std:: экспериментальный :: наблюдатель_ptr для неконстантного объекта, который не может изменять значение, на которое он указывает?
Это канонический способ создания std::experimental::observer_ptr
не-const
объект, который не может изменить значение, на которое указывает?
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
1 ответ
Не усложняйте дело. Просто делать
observer_ptr<const int> p{&i};
И все нормально.
Вы также можете сделать это согласно спецификации:
observer_ptr p{&std::as_const(i)};
но GCC и Clang, похоже, расходятся с этой спецификацией. Реализация использует полное имя для(element_type*)
конструктор, тем самым блокируя вывод аргументов шаблона класса.
Так же, как std::make_pair
, make_observer
существует потому, что библиотека Основы 2 TS создана в эпоху до C++17. В то время не существовало вывода аргументов шаблона класса. В настоящее время нам редко требуется отдельная функция make, напримерstd::make_pair
(контрпример: обертки ссылок, см. Полезностьstd::make_pair
а также std::make_tuple
в C++ 1z), и аналогично нам редко требуетсяmake_observer
.
Следовательно, нет смысла говорить о "каноническом" способе использования функции, предшествующей C++17, например observer_ptr
в C++17. Конечно, мы можем использовать вывод аргументов шаблона класса, если он действительно работает. Это просто даже не учтено при разработкеobserver_ptr
.