std:: addressof
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Определено в заголовочном файле
<memory>
|
||
|
template
<
class
T
>
T * addressof ( T & arg ) noexcept ; |
(1) |
(начиная с C++11)
(constexpr начиная с C++17) |
|
template
<
class
T
>
const T * addressof ( const T && ) = delete ; |
(2) | (начиная с C++11) |
|
Выражение
|
(начиная с C++17) |
Содержание |
Параметры
| arg | - | lvalue объект или функция |
Возвращаемое значение
Указатель на arg .
Возможная реализация
Приведенная ниже реализация не является constexpr , поскольку reinterpret_cast не может использоваться в константных выражениях. Требуется поддержка компилятора (см. ниже).
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; } |
` и `` был сохранен без изменений, как и требовалось. HTML-разметка и атрибуты также остались нетронутыми.
Корректная реализация этой функции требует поддержки компилятора: GNU libstdc++ , LLVM libc++ , Microsoft STL .
Примечания
| Макрос тестирования возможностей | Значение | Стандарт | Функция |
|---|---|---|---|
__cpp_lib_addressof_constexpr
|
201603L
|
(C++17) |
constexpr
std::addressof
|
constexpr
для
addressof
добавлен посредством
LWG2296
, и MSVC STL применяет это изменение к режиму C++14 как отчёт о дефектах.
Существуют некоторые особые случаи, когда использование встроенного
operator
&
является некорректным из-за
поиска, зависимого от аргументов
даже если он не перегружен, и вместо него может быть использован
std::addressof
.
template<class T> struct holder { T t; }; struct incomp; int main() { holder<holder<incomp>*> x{}; // &x; // ошибка: поиск, зависящий от аргументов, пытается инстанцировать holder<incomp> std::addressof(x); // OK }
Пример
operator & может быть перегружен для класса-обертки указателя для получения указателя на указатель:
#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) }
Возможный вывод:
Ctor this = 0x7fff59ae6e88 int** overload called with p = 0x7fff59ae6e90 Ptr overload called with p = 0x7fff59ae6e88
Отчеты о дефектах
Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| LWG 2598 | C++11 | std :: addressof < const T > мог брать адрес rvalues | запрещено с помощью удаленной перегрузки |
Смотрите также
|
аллокатор по умолчанию
(шаблон класса) |
|
|
[static]
|
получает разыменовываемый указатель на свой аргумент
(публичная статическая функция-член
std::pointer_traits<Ptr>
)
|