名前空間
変種
操作

std::reference_wrapper

提供: cppreference.com
< cpp‎ | utility‎ | functional
 
 
ユーティリティライブラリ
汎用ユーティリティ
日付と時間
関数オブジェクト
書式化ライブラリ (C++20)
(C++11)
関係演算子 (C++20で非推奨)
整数比較関数
(C++20)
スワップと型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
一般的な語彙の型
(C++11)
(C++17)
(C++17)
(C++17)
(C++17)

初等文字列変換
(C++17)
(C++17)
 
関数オブジェクト
関数ラッパー
(C++11)
(C++11)
関数の部分適用
(C++20)
(C++11)
関数呼び出し
(C++17)
恒等関数オブジェクト
(C++20)
参照ラッパー
reference_wrapper
(C++11)
(C++11)(C++11)
演算子ラッパー
否定子
(C++17)
検索子
制約付き比較子
古いバインダとアダプタ
(C++17未満)
(C++17未満)
(C++17未満)
(C++17未満)
(C++17未満)(C++17未満)(C++17未満)(C++17未満)
(C++20未満)
(C++20未満)
(C++17未満)(C++17未満)
(C++17未満)(C++17未満)

(C++17未満)
(C++17未満)(C++17未満)(C++17未満)(C++17未満)
(C++20未満)
(C++20未満)
 
 
ヘッダ <functional> で定義
template< class T >
class reference_wrapper;
(C++11以上)

std::reference_wrapper はコピー可能、代入可能なオブジェクトに参照をラップするクラステンプレートです。 通常は参照を保持できない標準コンテナ (std::vector のような) の内部に参照を格納するための仕組みとしてよく使用されます。

具体的には、 std::reference_wrapperT 型のオブジェクトへの参照または関数への参照を中心とする CopyConstructible かつ CopyAssignable なラッパーです。 std::reference_wrapper のインスタンスはオブジェクト (コピーしたりコンテナに格納したりできる) ですが、ベースとなる型を参照で取る関数で引数として使用できるように、 T& に暗黙に変換されます。

格納されている参照が Callable である場合、 std::reference_wrapper はそれと同じ引数で呼び出し可能です。

ヘルパー関数 std::ref および std::crefstd::reference_wrapper オブジェクトを生成するためによく使用されます。

std::reference_wrapperstd::bindstd::thread のコンストラクタ、ヘルパー関数 std::make_pair および std::make_tuple にオブジェクトを参照渡しするためにも使用されます。

std::reference_wrapperTriviallyCopyable であることが保証されます。

(C++17以上)

T は不完全型であっても構いません。

(C++20以上)

目次

[編集] メンバ型

定義
type T
result_type(C++17で非推奨)(C++20で削除) T が関数であれば T の戻り値の型。 そうでなければ定義されません
argument_type(C++17で非推奨)(C++20で削除) 1) TA1 型の引数をひとつ取る関数または関数ポインタの場合、 argument_typeA1 です

2) T がクラス T0 の引数を取らないメンバ関数ポインタの場合、 argument_typeT0* です (cv 修飾されるかもしれません)
3) T がメンバ型 T::argument_type を持つクラス型の場合、 argument_type はそのエイリアスです

first_argument_type(C++17で非推奨)(C++20で削除) 1) T が型 A1 および A2 の2つの引数を取る関数または関数ポインタの場合、 first_argument_typeA1 です

2) T がクラス T0 の引数をひとつ取るメンバ関数ポインタの場合、 first_argument_typeT0* です (cv 修飾されるかもしれません)
3) T がメンバ型 T::first_argument_type を持つクラス型の場合、 first_argument_type はそのエイリアスです

second_argument_type(C++17で非推奨)(C++20で削除) 1) T が型 A1 および A2 の2つの引数を取る関数または関数ポインタの場合、 second_argument_typeA2 です

2) T がクラス T0A1 引数をひとつ取るメンバ関数ポインタの場合、 second_argument_typeA1 です (cv 修飾されるかもしれません)
3) T がメンバ型 T::second_argument_type を持つクラス型の場合、 second_argument_type はそのエイリアスです

[編集] メンバ関数

新しい std::reference_wrapper オブジェクトに参照を格納します
(パブリックメンバ関数) [edit]
std::reference_wrapper を再束縛します
(パブリックメンバ関数) [edit]
格納されている参照にアクセスします
(パブリックメンバ関数) [edit]
格納されている関数を呼びます
(パブリックメンバ関数) [edit]

[編集] 推定ガイド(C++17以上)

[編集] 実装例

namespace detail {
template <class T> T& FUN(T& t) noexcept { return t; }
template <class T> void FUN(T&&) = delete;
}
 
template <class T>
class reference_wrapper {
public:
  // 型
  typedef T type;
 
  // 構築、コピー、破棄
  template <class U, class = decltype(
    detail::FUN<T>(std::declval<U>()),
    std::enable_if_t<!std::is_same_v<reference_wrapper, remove_cvref_t<U>>>()
  )>
  constexpr reference_wrapper(U&& u) noexcept(noexcept(detail::FUN<T>(std::forward<U>(u))))
    : _ptr(std::addressof(detail::FUN<T>(std::forward<U>(u)))) {}
  reference_wrapper(const reference_wrapper&) noexcept = default;
 
  // 代入
  reference_wrapper& operator=(const reference_wrapper& x) noexcept = default;
 
  // アクセス
  constexpr operator T& () const noexcept { return *_ptr; }
  constexpr T& get() const noexcept { return *_ptr; }
 
  template< class... ArgTypes >
  constexpr std::invoke_result_t<T&, ArgTypes...>
    operator() ( ArgTypes&&... args ) const {
    return std::invoke(get(), std::forward<ArgTypes>(args)...);
  }
 
private:
  T* _ptr;
};
 
// 推定ガイド
template<class T>
reference_wrapper(T&) -> reference_wrapper<T>;

[編集]

参照のコンテナとしての reference_wrapper の使用をデモンストレーションします。 これにより複数のインデックスを使用して同じコンテナにアクセスすることが可能となります。

#include <algorithm>
#include <list>
#include <vector>
#include <iostream>
#include <numeric>
#include <random>
#include <functional>
 
int main()
{
    std::list<int> l(10);
 
    std::iota(l.begin(), l.end(), -4);
    std::vector<std::reference_wrapper<int>> v(l.begin(), l.end());
 
    // list に shuffle を使用することはできません (ランダムアクセスを要求します) が、 vector には使用できます。
    std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()});
 
    std::cout << "Contents of the list: ";
    for (int n : l){ 
        std::cout << n << ' ';
    }
 
    std::cout << "\nContents of the list, as seen through a shuffled vector: ";
    for (int i : v){
        std::cout << i << ' ';
    }
 
    std::cout << "\n\nDoubling the values in the initial list...\n\n";
    for (int& i : l) {
        i *= 2;
    }
 
    std::cout << "Contents of the list, as seen through a shuffled vector: ";
    for (int i : v){
       std::cout << i << ' ';
    }
}

出力例:

Contents of the list: -4 -3 -2 -1 0 1 2 3 4 5 
Contents of the list, as seen through a shuffled vector: -1 2 -2 1 5 0 3 -3 -4 4 
Doubling the values in the initial list...
Contents of the list, as seen through a shuffled vector: -2 4 -4 2 10 0 6 -6 -8 8

[編集] 関連項目

(C++11)(C++11)
引数から推定される型の std::reference_wrapper を作成します
(関数テンプレート) [edit]
(C++11)
関数オブジェクトに1つ以上の引数をバインドします
(関数テンプレート) [edit]