Как вам создать 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

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

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.

Другие вопросы по тегам