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) 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->()); } |
[编辑] 注意
即使 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++11) |
提供有关类指针类型的信息 (类模板) |
[静态] (C++20)(可选) |
从花式指针获取原始指针(pointer_to 的逆操作)( std::pointer_traits<Ptr> 的公共静态成员函数) |