std::to_address

来自cppreference.com
< cpp‎ | memory
 
 
工具库
语言支持
类型支持(基本类型、RTTI)
库功能特性测试宏 (C++20)
动态内存管理
程序工具
协程支持 (C++20)
变参数函数
调试支持
(C++26)
三路比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用工具
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型运算
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
常用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
初等字符串转换
(C++17)
(C++17)

 
动态内存管理
未初始化内存算法
受约束的未初始化内存算法
分配器
垃圾收集器支持
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(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 所指向的地址,而不形成到被指向者的引用:

1) 缀饰指针重载:若表达式 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->());
}

注解

即使在 p 引用的存储中无已构造的对象时,也能使用 std::to_address,该情况下不能用 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);
}

参阅

提供关于指针式类型的信息
(类模板)
[静态] (C++20)(可选)
从缀饰指针获得裸指针( pointer_to 的反函数)
(std::pointer_traits<Ptr> 的公开静态成员函数)