Namespaces
Variants

std::unwrap_reference, std::unwrap_ref_decay

ja.cppreference.net より
 
 
ユーティリティライブラリ
言語サポート
型サポート (基本型、RTTI)
ライブラリ機能テストマクロ (C++20)
プログラムユーティリティ
可変引数関数
コルーチンサポート (C++20)
契約サポート (C++26)
三方比較
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

一般ユーティリティ
関係演算子 (C++20で非推奨)
整数比較関数
(C++20)(C++20)(C++20)    
(C++20)
swap と 型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
共通語彙型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
関数オブジェクト
関数呼び出し
(C++17)(C++23)
恒等関数オブジェクト
(C++20)
透過的演算子ラッパー
(C++14)
(C++14)
(C++14)
(C++14)  
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)

旧来のバインダとアダプタ
(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まで*)
 
ヘッダ <type_traits>
で定義<functional>
template< class T >
struct unwrap_reference;
(1) (C++20以上)
template< class T >
struct unwrap_ref_decay;
(2) (C++20以上)

任意の std::reference_wrapper をアンラップします: std::reference_wrapper<U> を U& に変更します。

1) T が std::reference_wrapper の特殊化である場合、それをアンラップします; そうでなければ、T は変更されません。
2) 非修飾型(decayed)の T が std::reference_wrapper の特殊化である場合、それをアンラップします; そうでなければ、T は非修飾型(decay)になります。

このページに記述されているテンプレートのいずれかにプログラムが特殊化を追加した場合、その動作は未定義です。

ネストされた型

型 定義
type

(1) U& もし T が std:: reference_wrapper < U > の場合; T それ以外の場合
(2) U& もし std:: decay_t < T > が std:: reference_wrapper < U > の場合; std:: decay_t < T > それ以外の場合

ヘルパー型

template < class T >
using unwrap_reference_t = unwrap_reference < T > :: type ;
(1) (C++20以降)
template < class T >
using unwrap_ref_decay_t = unwrap_ref_decay < T > :: type ;
(2) (C++20以降)

実装例

template<class T>
struct unwrap_reference { using type = T; };
template<class U>
struct unwrap_reference<std::reference_wrapper<U>> { using type = U&; };
template<class T>
struct unwrap_ref_decay : std::unwrap_reference<std::decay_t<T>> {};

注記

std::unwrap_ref_decay は、 std::make_pair および std::make_tuple で使用される変換と同じ変換を実行します。

機能テスト マクロ 値 標準 機能
__cpp_lib_unwrap_ref 201811L (C++20) std::unwrap_ref_decay および std::unwrap_reference

例

#include <cassert>
#include <functional>
#include <iostream>
#include <type_traits>
int main()
{
    static_assert(std::is_same_v<std::unwrap_reference_t<int>, int>);
    static_assert(std::is_same_v<std::unwrap_reference_t<const int>, const int>);
    static_assert(std::is_same_v<std::unwrap_reference_t<int&>, int&>);
    static_assert(std::is_same_v<std::unwrap_reference_t<int&&>, int&&>);
    static_assert(std::is_same_v<std::unwrap_reference_t<int*>, int*>);
    {
        using T = std::reference_wrapper<int>;
        using X = std::unwrap_reference_t<T>;
        static_assert(std::is_same_v<X, int&>);
    }
    {
        using T = std::reference_wrapper<int&>;
        using X = std::unwrap_reference_t<T>;
        static_assert(std::is_same_v<X, int&>);
    }
    static_assert(std::is_same_v<std::unwrap_ref_decay_t<int>, int>);
    static_assert(std::is_same_v<std::unwrap_ref_decay_t<const int>, int>);
    static_assert(std::is_same_v<std::unwrap_ref_decay_t<const int&>, int>);
    {
        using T = std::reference_wrapper<int&&>;
        using X = std::unwrap_ref_decay_t<T>;
        static_assert(std::is_same_v<X, int&>);
    }
    {
        auto reset = []<typename T>(T&& z)
        {
        //  x = 0; // エラー: Tがreference_wrapper<>の場合に動作しない
            // 通常の型に対してT&&をT&に変換
            // reference_wrapper<U>に対してT&&をU&に変換
            decltype(auto) r = std::unwrap_reference_t<T>(z);
            std::cout << "r: " << r << '\n';
            r = 0; // OK、rは参照型を持つ
        };
        int x = 1;
        reset(x);
        assert(x == 0);
        int y = 2;
        reset(std::ref(y));
        assert(y == 0);
    }
}

出力:

r: 1
r: 2

関連項目

CopyConstructible および CopyAssignable な参照ラッパー
(クラステンプレート)
引数の型から決定される型の pair オブジェクトを作成する
(関数テンプレート)
(C++11)
引数の型によって定義される型の tuple オブジェクトを作成する
(関数テンプレート)