std :: addressof是否否定了STL运算符和要求?

Nia*_*all 13 c++ stl c++11

为了使一个类型与C++ 03标准库"很好地",重载被认为是一个坏主意,operator&()因为地址需要正确使用该类型并重载它会产生意外问题; 这里的经典例子是ATL::CComBSTR.

  • 随着std::addressof()C++ 11及以后的出现,这是否否定了标准库中使用的类型的旧要求?
  • 是否在C++ 11中明确说明了要求(或从中删除),即规范要求使用的标准库是std::addressof()什么?

Rap*_*ptz 8

value_type容器的只有几个要求.它们主要依赖于容器,但对于一般情况,要求至少是MoveConstructibleMoveAssignable.

查看C++ 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's state is unspecified.                               |
 |                                                          |
 +----------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

§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's state is unspecified                                     |
  |                                                               |
  +---------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

根据具体情况,对容器有更多要求DefaultConstructible.但是,这两个要求operator&都不需要过载.它们主要处理value_type类型提供的而不是操作符重载的可构造性.

您可以在§17.6.3.1中找到其他表格.容器要求在§23中规定.


Nia*_*all 5

C++ 03复制构造要求明确地包括操作者地址的返回的对象的实际地址,如在评论中所指出§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 |
+------------+-------------+--------------------------+
Run Code Online (Sandbox Code Playgroud)

C++ 11简化了移动(并将可构造和可分配的定义复制)更基本的语法;

T ( rvalue ); // move construct
T u = rvalue; // move assign
T ( value ); // copy construct
T u = value; // copy assign
Run Code Online (Sandbox Code Playgroud)

它没有提到运算符的重载地址,但它也没有提到std::addressof明确需要(在某些.resize()函数之外).std::allocator但是,即使在存在重载的情况下,也明确要求类型的地址是正确的operator&().

总之,在规范中可能很少要求使用,std::addressof()但根据简化的要求和明确的对象地址要求; 使用std::addressof()(或类似)非常接近强制要求.

我的外卖是; 如果您正在编写通用代码并需要对象的地址,请使用std::addressof()并坚持安全.