Как вы должны создать std :: экспериментальный :: наблюдатель_ptr для неконстантного объекта, который не может изменить значение, на которое он указывает? - PullRequest
0 голосов
/ 05 октября 2019

Является ли это каноническим способом создания 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 Ответ

0 голосов
/ 06 октября 2019

Не усложняй дела. Просто сделайте

observer_ptr<const int> p{&i};

И все в порядке.

Вы также можете сделать это в соответствии с spec :

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.

...