std::to_address
来自 cppreference.com
定义在头文件 <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) 奇特指针 重载:如果表达式 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 的迭代器上使用。
功能测试 宏 | 值 | Std | 功能 |
---|---|---|---|
__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++11) |
提供有关指针类型的信息 (类模板) |
[静态] (C++20)(可选) |
从复杂指针中获取原始指针(pointer_to 的反向操作)( std::pointer_traits<Ptr> 的公共静态成员函数) |