Какие существуют законные причины для перегрузки унарного оператора &? - PullRequest
68 голосов
/ 27 июня 2011

Хорошо, я был вдохновлен сделать несколько ударов головой . Похоже, перегрузка operator& приводит к немалому количеству боли.

Какие существуют законные случаи для его перегрузки?

(Не могу сказать, что я когда-либо делал это ...)

Ответы [ 7 ]

52 голосов
/ 27 июня 2011

Кажется, я помню что-то вроде класса интеллектуального указателя, который переопределил operator&, потому что он хотел вернуть адрес содержащегося указателя, а не адрес объекта интеллектуального указателя. Не могу вспомнить, где я видел это или казалось ли это хорошей идеей в то время.

Ага, вспомнил: Microsoft CComPtr .

Редактировать: В целом, может иметь смысл при следующих условиях:

  • У вас есть объект, который маскируется под какой-то другой объект.
  • Этот объект может получить указатель на объект, который он маскирует.

Возврат чего-либо кроме законного указателя нарушил бы принцип наименьшего удивления .

10 голосов
/ 21 марта 2015

Это полезно при представлении операции & в лямбда-нотации заполнителя, например, &_1[_2].

10 голосов
/ 28 июня 2011

Унарная перегрузка & заставляет ваш объект вести себя как ссылка (в этом отношении).

Я почти уверен, что глупо пытаться предоставить альтернативы встроенным ссылкам, в частности, поскольку ссылки вообще не являются объектами в C ++, и у них нет своих собственных адресов. Экземпляры вашего пользовательского типа неизбежно являются объектами и имеют адреса, даже если вы отключите обычный способ получения этого адреса. Так что это никогда не идеальная имитация.

Но люди очень заинтересованы в пользовательских альтернативах указателям, поэтому я могу как-то увидеть, как кто-то может захотеть попробовать это. Я не уверен, что они будут избегать создания типа, который (неправильно) ведет себя так, что заставит его пользователей желать, чтобы они не беспокоились.

8 голосов
/ 21 сентября 2015

Четыре года спустя, еще один ответ.

Еще одно применение, которое я видел, - это когда вы работаете с языком C ++, но определяете свою семантику.Простой пример: Boost.Spirit.

Boost.Spirit, в частности Qi для синтаксического анализа, перегружает операторы на синтаксических анализаторах для обеспечения EBNF-подобного синтаксиса для указания произвольных объектов синтаксического анализатора.В частности, унарный оператор & перегружен, чтобы предоставить парсер And-Predicate .

парсер And-Predicate (& a)

Description

Синтаксические предикаты утверждают определенный условный синтаксис, который должен быть выполнен перед оценкой другой продукции.Подобно семантическим предикатам, eps, синтаксические предикаты не потребляют никакого ввода.И-предикат, & a, является положительным синтаксическим предикатом, который возвращает совпадение нулевой длины, только если его предикат совпадает.

Пример использования:

Базовый пример предварительного просмотра: убедитесь, что последний символ является точкой с запятой, но не используйте его, просто посмотрите на следующий символ:

test_phrase_parser("Hello ;", lit("Hello") >> &lit(';'), false);

Короче говоря, унарный & здесь не имеет никакого отношенияна указатели вообще;у него есть специфичная для домена семантика, которая применяется к объектам парсера Qi.

7 голосов
/ 16 сентября 2014

Я сделал это с хорошим эффектом в контексте DSL, который генерирует код LLVM. Пример проиллюстрирую. Скажем x и y являются значениями (то есть объектами типа value). Тогда выражение x+y испускает инструкцию ADD в некоторый поток кода. Весьма разумно, выражение &x испускает инструкцию, чтобы взять адрес x.

0 голосов
/ 13 мая 2014

Вы можете перегрузить адрес оператора, чтобы сделать его приватным.Это может быть полезно для реализации какой-либо схемы передачи жезлов, когда адрес жезла не может быть получен.Если конструкторы жезла скрыты, это может держать прицел жезла герметичным.

0 голосов
/ 04 марта 2012

Однажды я использовал переопределение оператора & (без изменения его поведения) как приватное для класса, чтобы защитить от случайного создания умного указателя на объект, созданный в стеке.Все еще не уверен, была ли это действительно хорошая идея ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...