std::to_address
来自 cppreference.cn
定义于头文件 <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> 的公共静态成员函数) |