Namespaces
Variants

std::reference_wrapper

cppreference.net에서 가져옴
 
 
유틸리티 라이브러리
일반 유틸리티
관계 연산자 (C++20에서 폐지됨)
정수 비교 함수
(C++20)(C++20)(C++20)    
(C++20)
스왑 및 타입 연산
(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까지*)
 
 
헤더 <functional>
template< class T >
class reference_wrapper;
에 정의됨 (C++11부터)

std::reference_wrapper는 참조를 복사 가능하고 대입 가능한 객체로 감싸는 클래스 템플릿입니다.

구체적으로, std::reference_wrapper는 CopyConstructible 및 CopyAssignable인, 타입 T의 객체 참조 또는 함수 참조에 대한 래퍼입니다. std::reference_wrapper의 인스턴스는 객체입니다 (복사되거나 컨테이너에 저장될 수 있음). 그러나 이들은 T&에 암시적으로 변환 가능하므로, 기본 타입을 참조로 받는 함수에 인수로 사용될 수 있습니다.

저장된 참조가 Callable이면, std::reference_wrapper는 동일한 인수로 호출 가능합니다.

도우미 함수 std::ref와 std::cref는 std::reference_wrapper 객체를 생성하는 데 자주 사용됩니다.

std::reference_wrapper는 객체를 std::bind, std::thread의 생성자, 또는 도우미 함수 std::make_pair 및 std::make_tuple에 참조로 전달하는 데 사용됩니다. 또한 일반적으로 참조를 보유할 수 없는 표준 컨테이너(예: std::vector) 내에 참조를 저장하는 메커니즘으로 사용될 수도 있습니다.

std::reference_wrapper는 TriviallyCopyable이 보장됩니다.

(C++17부터)

T는 불완전한 타입일 수 있습니다.

(C++20부터)

멤버 타입

타입 정의
type T
result_type
(C++17에서 사용 중단됨)
(C++20에서 제거됨)
T 가 함수일 경우의 반환 타입. 그렇지 않은 경우 정의되지 않음.
argument_type
(C++17에서 사용 중단됨)
(C++20에서 제거됨)
  • T 가 A1 타입의 인수를 하나 받는 함수나 함수 포인터인 경우, argument_type 은 A1
  • T 가 인수를 받지 않는 클래스 T0 의 멤버 함수 포인터인 경우, argument_type 은 T0 * (cv 한정자 가능)
  • T 가 멤버 타입 T :: argument_type 을 가진 클래스 타입인 경우, argument_type 은 해당 타입의 별칭
first_argument_type
(C++17에서 사용 중단됨)
(C++20에서 제거됨)
  • T 가 A1 과 A2 타입의 인수 두 개를 받는 함수나 함수 포인터인 경우, first_argument_type 은 A1
  • T 가 인수 하나를 받는 클래스 T0 의 멤버 함수 포인터인 경우, first_argument_type 은 T0 * (cv 한정자 가능)
  • T 가 멤버 타입 T :: first_argument_type 을 가진 클래스 타입인 경우, first_argument_type 은 해당 타입의 별칭
second_argument_type
(C++17에서 사용 중단됨)
(C++20에서 제거됨)
  • T 가 A1 과 A2 타입의 인수 두 개를 받는 함수나 함수 포인터인 경우, second_argument_type 은 A2
  • T 가 A1 인수 하나를 받는 클래스 T0 의 멤버 함수 포인터인 경우, second_argument_type 은 A1 (cv 한정자 가능)
  • T 가 멤버 타입 T :: second_argument_type 을 가진 클래스 타입인 경우, second_argument_type 은 해당 타입의 별칭

멤버 함수

새로운 std::reference_wrapper 객체에 참조를 저장함
(public member function)
std::reference_wrapper 를 재바인딩함
(public member function)
저장된 참조에 접근함
(public member function)
저장된 함수를 호출함
(public member function)

비멤버 함수

reference_wrapper 객체들을 저장된 참조로 비교
(함수)

추론 가이드 (C++17부터)

헬퍼 클래스

reference_wrapper 와 non- reference_wrapper 의
공통 참조 타입을 결정함
(클래스 템플릿 특수화)

가능한 구현

namespace detail
{
    template<class T> constexpr T& FUN(T& t) noexcept { return t; }
    template<class T> void FUN(T&&) = delete;
}
template<class T>
class reference_wrapper
{
public:
    // 타입
    using type = T;
    // 생성/복사/소멸
    template<class U, class = decltype(
        detail::FUN<T>(std::declval<U>()),
        std::enable_if_t<!std::is_same_v<reference_wrapper, std::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
            noexcept(std::is_nothrow_invocable_v<T&, ArgTypes...>)
    {
        return std::invoke(get(), std::forward<ArgTypes>(args)...);
    }
private:
    T* _ptr;
};
// 추론 가이드
template<class T>
reference_wrapper(T&) -> reference_wrapper<T>;

예제

std::reference_wrapper 를 참조 컨테이너로 사용하는 방법을 보여주며, 이를 통해 여러 인덱스를 사용하여 동일한 컨테이너에 접근할 수 있습니다.

#include <algorithm>
#include <functional>
#include <iostream>
#include <list>
#include <numeric>
#include <random>
#include <vector>
void println(auto const rem, std::ranges::range auto const& v)
{
    for (std::cout << rem; auto const& e : v)
        std::cout << e << ' ';
    std::cout << '\n';
}
int main()
{
    std::list<int> l(10);
    std::iota(l.begin(), l.end(), -4);
    // can't use shuffle on a list (requires random access), but can use it on a vector
    std::vector<std::reference_wrapper<int>> v(l.begin(), l.end());
    std::ranges::shuffle(v, std::mt19937{std::random_device{}()});
    println("Contents of the list: ", l);
    println("Contents of the list, as seen through a shuffled vector: ", v);
    std::cout << "Doubling the values in the initial list...\n";
    std::ranges::for_each(l, [](int& i) { i *= 2; });
    println("Contents of the list, as seen through a shuffled vector: ", v);
}

가능한 출력:

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 생성
(함수 템플릿)
(C++11)
함수 객체에 하나 이상의 인수를 바인딩
(함수 템플릿)
std::reference_wrapper 내에 래핑된 참조 타입 획득
(클래스 템플릿)