std:: addressof
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Definido en el encabezado
<memory>
|
||
|
template
<
class
T
>
T * addressof ( T & arg ) noexcept ; |
(1) |
(desde C++11)
(constexpr desde C++17) |
|
template
<
class
T
>
const T * addressof ( const T && ) = delete ; |
(2) | (desde C++11) |
|
La expresión
|
(desde C++17) |
Contenidos |
Parámetros
| arg | - | objeto o función lvalue |
Valor de retorno
Puntero a arg .
Implementación posible
La implementación a continuación no es constexpr , porque reinterpret_cast no se puede utilizar en una expresión constante. Se necesita soporte del compilador (ver más abajo).
template<class T> typename std::enable_if<std::is_object<T>::value, T*>::type addressof(T& arg) noexcept { return reinterpret_cast<T*>( &const_cast<char&>( reinterpret_cast<const volatile char&>(arg))); } template<class T> typename std::enable_if<!std::is_object<T>::value, T*>::type addressof(T& arg) noexcept { return &arg; } |
La implementación correcta de esta función requiere soporte del compilador: GNU libstdc++ , LLVM libc++ , Microsoft STL .
Notas
| Macro de prueba de características | Valor | Std | Característica |
|---|---|---|---|
__cpp_lib_addressof_constexpr
|
201603L
|
(C++17) |
constexpr
std::addressof
|
constexpr
para
addressof
se añade mediante
LWG2296
, y MSVC STL aplica el cambio al modo C++14 como un informe de defectos.
Hay algunos casos extraños donde el uso del
operator
&
integrado es incorrecto debido a la
búsqueda dependiente de argumentos
incluso cuando no está sobrecargado, y se puede utilizar
std::addressof
en su lugar.
template<class T> struct holder { T t; }; struct incomp; int main() { holder<holder<incomp>*> x{}; // &x; // error: la búsqueda dependiente de argumento intenta instanciar holder<incomp> std::addressof(x); // OK }
Ejemplo
operator & puede sobrecargarse para una clase contenedora de punteros para obtener un puntero a puntero:
#include <iostream> #include <memory> template<class T> struct Ptr { T* pad; // add pad to show difference between 'this' and 'data' T* data; Ptr(T* arg) : pad(nullptr), data(arg) { std::cout << "Ctor this = " << this << '\n'; } ~Ptr() { delete data; } T** operator&() { return &data; } }; template<class T> void f(Ptr<T>* p) { std::cout << "Ptr overload called with p = " << p << '\n'; } void f(int** p) { std::cout << "int** overload called with p = " << p << '\n'; } int main() { Ptr<int> p(new int(42)); f(&p); // calls int** overload f(std::addressof(p)); // calls Ptr<int>* overload, (= this) }
Salida posible:
Ctor this = 0x7fff59ae6e88 int** overload called with p = 0x7fff59ae6e90 Ptr overload called with p = 0x7fff59ae6e88
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 2598 | C++11 | std :: addressof < const T > podría tomar la dirección de rvalues | prohibido mediante una sobrecarga eliminada |
Véase también
|
el asignador predeterminado
(plantilla de clase) |
|
|
[static]
|
obtiene un puntero desreferenciable a su argumento
(función miembro estática pública de
std::pointer_traits<Ptr>
)
|