In order for a type to "play nicely" with the C++03 Standard Libraries, it was considered a bad idea to overload the operator&()
since the address was need to correctly use the type and overloading it created unexpected problems; classic example here is ATL::CComBSTR
.
std::addressof()
in C++11 and on, does this negate that old requirement(s) on the types being used in the standard library?std::addressof()
?The value_type
of a container only has a few requirements. They depend mainly on the container, but for the general case the requirements are at the very least MoveConstructible
and MoveAssignable
.
Looking at the C++11 standard tables for what these requirements mean, you get this:
§ 17.6.3.1 Table 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 Table 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 |
| |
+---------------------------------------------------------------+
There are more requirements given to a container depending on what it is, like DefaultConstructible
. However, neither of the requirements require operator&
to not be overloaded. They mainly deal with the constructibility of the value_type
rather than the operator overloads provided by the type.
You can find the other tables over at § 17.6.3.1. The container requirements are specified over at § 23.
The C++03 CopyConstructible requirements explicitly included the requirement that the address-of operator returned the actual address of the object, as noted in the comments § 20.1.3 (Table 30), hence types that overloaded that operator could run into problems with the Standard Library.
+------------+-------------+--------------------------+
| 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 simplifies the move (and copy constructible and assignable definitions) to a more basic syntax;
T ( rvalue ); // move construct
T u = rvalue; // move assign
T ( value ); // copy construct
T u = value; // copy assign
It makes no mention of the overloaded address of operator, but it also make little mention of std::addressof
explicitly being required (outside some .resize()
functions). std::allocator
does however explicitly require the address of the types to be correct even in the presence of overloaded operator&()
.
In conclusion, there may be little in the specification to mandate the use of std::addressof()
but in light of the simplified requirements and explicit object address requirements; the use of std::addressof()
(or similar) is very close to being mandated.
My take-away here is; if you are writing generic code and require the address of an object, use std::addressof()
and stick to being on the safe side.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With