Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::addressof是否否定STL运算符&;要求_C++_C++11_Stl - Fatal编程技术网

C++ std::addressof是否否定STL运算符&;要求

C++ std::addressof是否否定STL运算符&;要求,c++,c++11,stl,C++,C++11,Stl,为了使类型与C++03标准库“配合良好”,重载操作符(&())被认为是一个坏主意,因为地址需要正确使用类型,而重载它会产生意外问题;这里的经典示例是ATL::CComBSTR 随着C++11及更高版本中std::addressof()的出现,这是否否定了对标准库中使用的类型的旧要求 该要求是否在C++11标准中明确规定(或从中删除),即规范是否强制标准库使用std::addressof() 容器的值类型只有几个要求。它们主要取决于容器,但对于一般情况,要求至少是MoveConstructibl

为了使类型与C++03标准库“配合良好”,重载
操作符(&()
)被认为是一个坏主意,因为地址需要正确使用类型,而重载它会产生意外问题;这里的经典示例是
ATL::CComBSTR

  • 随着C++11及更高版本中
    std::addressof()
    的出现,这是否否定了对标准库中使用的类型的旧要求
  • 该要求是否在C++11标准中明确规定(或从中删除),即规范是否强制标准库使用
    std::addressof()

容器的
值类型
只有几个要求。它们主要取决于容器,但对于一般情况,要求至少是
MoveConstructible
MoveAssignable

查看C++11标准表了解这些要求的含义,您会发现:

§17.6.3.1表20(
MoveConstructible
):

+----------------------------------------------------------+
|表达式|后条件|
|----------------------------------------------------------+
|tu=rv;|u等于|
||施工前rv的值|
+----------------------------------------------------------+
|TU(rv);|T(rv)等于|
||施工前rv的值|
+----------------------------------------------------------+
|rv的状态未指定|
|                                                          |
+----------------------------------------------------------+
§17.6.3.1表22(
MoveAssignable

+-----------+--------------+-------------+----------------------+
|表达式|返回类型|返回值|后置条件|
|-----------|--------------|-------------|----------------------|
|t=rv;|T&| T | T等于|
|| | | rv的值|
|| | |作业前|
|           |              |             |                      |
+---------------------------------------------------------------+
|rv的状态未指明|
|                                                               |
+---------------------------------------------------------------+
根据容器的不同,它有更多的要求,比如
DefaultConstructible
。但是,这两种要求都不要求
运算符&
过载。它们主要处理
value\u类型的可构造性,而不是类型提供的运算符重载


您可以在§17.6.3.1中找到其他表格。容器要求在§23中有详细说明。

C++03可复制的要求明确包括操作员地址返回对象实际地址的要求,如注释§20.1.3(表30)中所述,因此,重载该运算符的类型可能会在标准库中遇到问题

+------------+-------------+--------------------------+
|表达式|返回类型|要求|
+------------+-------------+--------------------------+
|T(T)| | T等于T(T)|
+------------+-------------+--------------------------+
|T(u)| | u等于T(u)|
+------------+-------------+--------------------------+
|t.~t()|
+------------+-------------+--------------------------+
|&t | t*|表示t的地址|
+------------+-------------+--------------------------+
|&u | const T*|表示u的地址|
+------------+-------------+--------------------------+
C++11将移动(以及复制可构造和可分配的定义)简化为更基本的语法

T(右值);//移动构造
tu=右值;//移动分配
T(值);//复制构造
tu=值;//复制分配
它没有提到运算符的重载地址,但也很少提到显式需要的
std::addressof
(在某些
.resize()
函数之外)<但是,即使存在重载的
运算符(&()
),分配程序也明确要求类型的地址正确

总之,规范中可能很少强制使用
std::addressof()
,但考虑到简化的要求和明确的对象地址要求;
std::addressof()
(或类似)的使用已接近强制要求


我的外卖是;如果您正在编写泛型代码并需要对象的地址,请使用
std::addressof()
,并注意安全。

C++03中的“要求”是什么?你确定这是一个要求而不是一个建议吗?CComBSTR有什么问题?“容器要求它们的元素是可复制和可分配的(C++03 23.1/3),而可复制要求&t返回一个t*,即t的地址(20.1.3/1)”,重载一元
运算符&
会让你成为一个糟糕的程序员,无论您的代码是否与STL一起工作。所引用的要求在C++11中不再存在,这意味着容器必须容忍使用
std::addressof
或类似机制重载
运算符和
的类型。此处突出显示C++03和C++11之间的差异。