Skip to content

Latest commit

 

History

History
102 lines (82 loc) · 2.05 KB

unwrap_reference.md

File metadata and controls

102 lines (82 loc) · 2.05 KB

unwrap_reference

  • functional[meta header]
  • std[meta namespace]
  • class template[meta id-type]
  • cpp20[meta cpp]
namespace std {
  template <class T>
  struct unwrap_reference;
}

概要

reference_wrapper<T>型をT&型に展開する。

効果

  • テンプレートパラメータTreference_wrapper<T>であれば、T&型をメンバ型typeとして定義する
  • そうでなければ、テンプレートパラメータTをメンバ型typeとして定義する

#include <cassert>
#include <functional>
#include <type_traits>

template <class T>
struct X {
  T t;
};

template <class T>
X<typename std::unwrap_reference<T>::type> f(T t)
{
  return X<typename std::unwrap_reference<T>::type>{t};
}

int main()
{
  static_assert(std::is_same_v<
    std::unwrap_reference<std::reference_wrapper<int>>::type,
    int&
  >);

  static_assert(std::is_same_v<
    std::unwrap_reference<int>::type,
    int
  >);

  static_assert(std::is_same_v<
    std::unwrap_reference<const int&>::type,
    const int&
  >);

  // Xクラスに参照を保持させたい場合にstd::ref()を通して渡し、
  // そうでなければ単に引数を転送する。
  int a = 3;
  X x = f(std::ref(a));
  x.t = 2;
  assert(a == 2);

  int b = 4;
  X y = f(b);
  y.t = 5;
  assert(y.t == 5);
  assert(b == 4);
}
  • std::unwrap_reference[color ff0000]
  • std::reference_wrapper[link ref.md]
  • std::ref[link ref.md]

出力

実装例

namespace std {
  template <class T>
  struct unwrap_reference { using type = T; }

  template <class T>
  struct unwrap_reference<reference_wrapper<T>> { using type = T&; }
}
  • reference_wrapper[link reference_wrapper.md]

バージョン

言語

  • C++20

処理系

参照