std :: addressof是否取消了STL运算符&需求?

时间:2014-08-27 07:31:16

标签: c++ c++11 stl

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

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

2 个答案:

答案 0 :(得分: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.                               |
 |                                                          |
 +----------------------------------------------------------+

§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                                     |
  |                                                               |
  +---------------------------------------------------------------+

根据容器的要求,给容器提出了更多要求,例如DefaultConstructible。但是,这两个要求都不要求operator&不会超载。它们主要处理value_type的可构造性,而不是类型提供的运算符重载。

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

答案 1 :(得分:5)

C ++ 03 CopyConstructible 要求明确包括要求address-of运算符返回对象的实际地址,如注释§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 |
+------------+-------------+--------------------------+

C ++ 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() 并坚持安全。