Почему перегрузка оператора &() запрещена для классов, хранящихся в контейнерах 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. Вам просто не разрешено изменять значение или тип встроенного.)