最終更新日時(UTC):
が更新

履歴 編集

function template
<memory>

std::to_address(C++20)

namespace std {
  template <class Ptr>
  constexpr auto to_address(const Ptr& p) noexcept; // (1)

  template <class T>
  constexpr T* to_address(T* p) noexcept;           // (2)
}

概要

ポインタと見なせるオブジェクトからアドレスを取得する。

要件

  • (2) : 型Tが関数ではないこと

戻り値

  • (1) : 式pointer_traits<Ptr>::to_address(p)が有効であればその戻り値を返す。そうでなければ、to_address(p.operator->())を返す
  • (2) : pを返す

例外

投げない

ポインタの例

#include <iostream>
#include <memory>

int main()
{
  int x = 3;
  int* p = &x;

  // ポインタからアドレスを取得する。
  // なにもせず、渡したものが返る
  int* result1 = std::to_address(p);
  std::cout << *result1 << std::endl;

  // スマートポインタからアドレスを取得する。
  // スマートポインタが所有権管理しているポインタが返る
  std::shared_ptr<int> sp {new int(1)};
  int* result2 = std::to_address(sp);
  std::cout << *result2 << std::endl;
}

出力

3
1

イテレータの例

#include <iostream>
#include <vector>

int main()
{
  std::vector<int> vec = {1, 2, 3, 4};

  // vectorやstring等のイテレータはcontiguousではあるが、実装によってポインタではない場合がある
  auto it = vec.begin();
  auto end = vec.end();

  // contiguousなイテレータをその要素へのポインタに変換する
  int* p = std::to_address(it);

  // 特に、終端イテレータからポインタへの変換で未定義動作を回避できる
  int* ep = std::to_address(end);
  // この様にしてしまうと、オブジェクトを指していないポインタのデリファレンスとなり未定義動作
  //int* ep = &*end;

  std::cout << *p << '\n';
  std::cout << *(ep - 1);
}

出力

1
4

バージョン

言語

  • C++20

処理系

参照