std::to_address
定义于头文件 <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 参数的合法对象。
to_address
的缀饰指针重载审查 std::pointer_traits<Ptr> 特化。若实例化该特化自身为谬构(往往是因为无法定义 element_type
),则导致立即语境外的硬错误并使得程序为谬构。
示例
运行此代码
#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> 的公开静态成员函数) |