Почему перегрузка оператора &() запрещена для классов, хранящихся в контейнерах STL?

Внезапно в в этой статье ( "проблема 2" ) Я вижу утверждение, что С++ Standard запрещает использование STL-контейнеров для хранения элементов класса if этот класс имеет перегруженный operator&().

Перегрузка operator&() действительно может быть проблематичной, но выглядит так, как по умолчанию оператор "адрес-из" может быть легко использован через набор грязно-выглядящих приемов, которые используются в boost::addressof() и считаются переносимыми и стандартными компиляторами.

Почему существует перегрузка operator&() для классов, хранящихся в контейнерах STL, в то время как обходной путь boost::addressof() существует?

Ответ 1

Не смотря на ссылки, я полагаю, что трюки в boost::addressof() были изобретены после требования не перегружать унарный префикс & для объектов, которые должны храниться в контейнерах std lib.

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

Ответ 2

Вероятно, потому что это меньше хлопот, чтобы просто запретить использование перегруженных классов operator &(), чем создавать функцию std:: addressof() и заменять каждое использование и в его контейнере кодом.

Ответ 3

Стандарт был завершен в 1998 году с исправлениями в 2003 году, тогда как boost::addressof даты до в начале 2002 года.

Кроме того, не ясно, что addressof является ответом. Перегрузки operator&() указывают на то, что необработанных указателей следует избегать. Элемент Allocator::address предоставляет лучший интерфейс для получения от Allocator::reference до Allocator::pointer, поэтому в общей теории вы должны иметь возможность эффективно внедрять переопределение operator& в класс с хорошим поведением с помощью специального распределителя.

Учитывая, что ссылки делают почти все, что делают указатели, а интерфейс Allocator абстрагирует все остальное, не должно быть необходимости в необработанных указателях.

Удобство для разработчиков библиотеки не должно быть проблемой. Нечеткая семантика Allocator::pointer является проблемой, и то, что я читал до сих пор в С++ 0x, не выясняет, что вверх.

С++ 0x удаляет любое упоминание operator& из CopyConstructible и, кроме того, не требует ничего - конструктивного для аргументов контейнера вообще - пользователь может придерживаться emplace. Даже vector требует только Destructible, хотя я предполагаю, что на самом деле использование insert или erase потребует больше.

(Обратите внимание, что при строжайшем чтении перегрузки не запрещены в С++ 03. Вам просто не разрешено изменять значение или тип встроенного.)