Namespaces
Variants

std:: to_address

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
定义于头文件 <memory>
template < class Ptr >
constexpr auto to_address ( const Ptr & p ) noexcept ;
(1) (C++20 起)
template < class T >
constexpr T * to_address ( T * p ) noexcept ;
(2) (C++20 起)

在不形成对 p 所指向对象的引用的情况下,获取 p 所表示的地址。

1) Fancy pointer 重载:若表达式 std:: pointer_traits < Ptr > :: to_address ( p ) 合法,则返回该表达式的结果。否则返回 std :: to_address ( p. operator - > ( ) )
2) 原始指针重载:如果 T 是函数类型,则程序非良构。否则,返回未经修改的 p

目录

参数

p - 花式指针或原始指针

返回值

原始指针,表示与 p 相同的地址。

可能的实现

template<class T>
constexpr T* to_address(T* p) noexcept
{
    static_assert(!std::is_function_v<T>);
    return p;
}
template<class T>
constexpr auto to_address(const T& p) noexcept
{
    if constexpr (requires{ std::pointer_traits<T>::to_address(p); })
        return std::pointer_traits<T>::to_address(p);
    else
        return std::to_address(p.operator->());
}

注释

std::to_address 即使当 p 未指向已构造对象的存储空间时也可使用,此时无法使用 std:: addressof ( * p ) ,因为 std:: addressof 的参数没有有效对象可供绑定。

std::to_address 的花式指针重载会检查 std:: pointer_traits < Ptr > 的特化。如果实例化该特化本身即为病式(通常是因为无法定义 element_type ),这将导致立即上下文之外的硬错误,并使程序处于病式状态。

std::to_address 还可用于满足 std::contiguous_iterator 要求的迭代器。

功能测试 标准 功能
__cpp_lib_to_address 201711L (C++20) 将指针转换为原始指针的工具( std::to_address

示例

#include <memory>
template<class A>
auto allocator_new(A& a)
{
    auto p = a.allocate(1);
    try
    {
        std::allocator_traits<A>::construct(a, std::to_address(p));
    }
    catch (...)
    {
        a.deallocate(p, 1);
        throw;
    }
    return p;
}
template<class A>
void allocator_delete(A& a, typename std::allocator_traits<A>::pointer p)
{
    std::allocator_traits<A>::destroy(a, std::to_address(p));
    a.deallocate(p, 1);
}
int main()
{
    std::allocator<int> a;
    auto p = allocator_new(a);
    allocator_delete(a, p);
}

参见

提供关于指针类类型的信息
(类模板)
[static] (C++20) (optional)
从智能指针获取原始指针( pointer_to 的逆操作)
( std::pointer_traits<Ptr> 的公开静态成员函数)