std::to_address
From 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) Fancy pointer オーバーロード: 式 std::pointer_traits<Ptr>::to_address(p) が整形式の場合、その式の結果を返します。そうでない場合、std::to_address(p.operator->()) を返します。
2) Raw pointer オーバーロード:
T が関数型の場合、プログラムは不適格です。そうでない場合、p を変更せずに返します。目次 |
[編集] パラメーター
| p | - | fancy または raw ポインター |
[編集] 戻り値
p と同じアドレスを表す raw ポインター。
[編集] 可能な実装
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->()); } |
[編集] 備考
std::to_address は、p がオブジェクトが構築されていないストレージを参照している場合でも使用できます。この場合、std::addressof(*p) のパラメーターがバインドする有効なオブジェクトがないため、std::addressof は使用できません。
std::to_address の fancy pointer オーバーロードは、std::pointer_traits<Ptr> 特殊化を検査します。この特殊化のインスタンス化自体が不適格な場合(通常、element_type を定義できないため)、即時のコンテキスト外でハードエラーが発生し、プログラムが不適格になります。
std::to_address は、std::contiguous_iterator を満たすイテレーターにも使用できます。
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_to_address |
201711L |
(C++20) | ポインターを raw ポインターに変換するユーティリティ(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) |
ポインタライクな型に関する情報を提供します (クラステンプレート) |
| [static] (C++20)(optional) |
ファンシーポインターから生ポインターを取得する(pointer_to の逆)( std::pointer_traits<Ptr> の public static メンバー関数) |