Подтвердить что ты не робот

Указывает std:: addressof на отказ оператора STL и требования?

Для того, чтобы тип "хорошо играл" с стандартными библиотеками С++ 03, считалось плохой идеей перегружать operator&(), поскольку адрес должен был правильно использовать тип и перегружать его создавали непредвиденные проблемы; Классический пример здесь ATL::CComBSTR.

  • С появлением std::addressof() в С++ 11 и далее это отменяет это старое требование для типов, используемых в стандартной библиотеке?
  • Является ли требование, явно указанное в (или удаляемом) стандартом в С++ 11, то есть стандартная библиотека, уполномоченная спецификацией использовать std::addressof()?
4b9b3361

Ответ 1

В контейнере value_type имеется только несколько требований. Они зависят главным образом от контейнера, но в общем случае требования минимальны MoveConstructible и MoveAssignable.

Глядя на стандартные таблицы С++ 11, для которых эти требования означают, вы получите следующее:

§ 17.6.3.1 Таблица 20 (MoveConstructible):

 +----------------------------------------------------------+
 | Expression         |       Post Condition                |
 |----------------------------------------------------------+
 | T u = rv;          | u is equivalent to the              |
 |                    | value of rv before the construction |
 +----------------------------------------------------------+
 | T u(rv);           | T(rv) is equivalent to the          |
 |                    | value of rv before the construction |
 +----------------------------------------------------------+
 | rv state is unspecified.                               |
 |                                                          |
 +----------------------------------------------------------+

§ 17.6.3.1 Таблица 22 (MoveAssignable).

  +-----------+--------------+-------------+----------------------+
  | Expression|  Return Type | Return value| Post Condition       |
  |-----------|--------------|-------------|----------------------|
  | t = rv;   |  T&          | t           | t is equivalent to   |
  |           |              |             | the value of rv      |
  |           |              |             | before the assignment|
  |           |              |             |                      |
  +---------------------------------------------------------------+
  | rv state is unspecified                                     |
  |                                                               |
  +---------------------------------------------------------------+

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

Вы можете найти другие таблицы в § 17.6.3.1. Требования к контейнеру указаны в § 23.

Ответ 2

В требованиях С++ 03 CopyConstructible явно указано требование о том, чтобы адрес-оператор возвращал фактический адрес объекта, как указано в комментариях § 20.1.3 (таблица 30), следовательно типы, которые перегрузили этот оператор, могут столкнуться с проблемами со стандартной библиотекой.

+------------+-------------+--------------------------+
| expression | return type | requirement              |
+------------+-------------+--------------------------+
| T(t)       |             | t is equivalent to T(t)  |
+------------+-------------+--------------------------+
| T(u)       |             | u is equivalent to T(u)  |
+------------+-------------+--------------------------+
| t.~T()     |             |                          |
+------------+-------------+--------------------------+
| &t         | T*          | denotes the address of t |
+------------+-------------+--------------------------+
| &u         | const T*    | denotes the address of u |
+------------+-------------+--------------------------+

С++ 11 упрощает перемещение (и копирует конструктивные и присваиваемые определения) в более простой синтаксис;

T ( rvalue ); // move construct
T u = rvalue; // move assign
T ( value ); // copy construct
T u = value; // copy assign

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

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

Мой взнос здесь; если вы пишете общий код и требуете адрес объекта, используйте std::addressof() и придерживайтесь того, чтобы быть в безопасности.