functional_reference_wrapper

functional_reference_wrapper (참조 래퍼)

std::reference_wrapper는 참조를 복사하고 대입할 수 있는 객체로 감싸는 클래스 템플릿이에요. 이 페이지에서는 std::reference_wrapper의 정의, 멤버 타입, 멤버 함수, 비멤버 함수, 구현 예시와 사용 예제를 설명할게요.

출처: cppreference

본문

정의

<functional> 헤더에 정의되어 있어요.

template < class T > class reference_wrapper ; (C++11 이후)

std::reference_wrapper는 참조를 복사 가능하고 대입 가능한 객체로 감싸는 클래스 템플릿이에요. 구체적으로, std::reference_wrapperT 타입의 객체나 함수에 대한 참조를 감싸는 CopyConstructible 및 CopyAssignable 래퍼예요. std::reference_wrapper의 인스턴스는 객체이므로 복사하거나 컨테이너에 저장할 수 있지만, T&로 암시적으로 변환되기 때문에 기본 타입을 참조로 받는 함수에 인자로 사용할 수 있어요.

저장된 참조가 Callable이라면 std::reference_wrapper도 동일한 인자로 호출 가능해요.

헬퍼 함수 std::refstd::crefstd::reference_wrapper 객체를 생성할 때 자주 사용돼요.

std::reference_wrapperstd::bind, std::thread의 생성자, 또는 헬퍼 함수 std::make_pairstd::make_tuple에 객체를 참조로 전달할 때 사용돼요. 또한 일반적으로 참조를 보관할 수 없는 표준 컨테이너(예: std::vector)에 참조를 저장하는 메커니즘으로도 사용할 수 있어요.

std::reference_wrapper는 TriviallyCopyable임이 보장돼요. (C++17 이후)
T는 불완전 타입일 수 있어요. (C++20 이후)

멤버 타입

type 정의
type T
result_type (C++17에서 deprecated, C++20에서 제거) T가 함수라면 T의 반환 타입. 그렇지 않으면 정의되지 않음.
argument_type (C++17에서 deprecated, C++20에서 제거) T가 하나의 인자 A1을 받는 함수 또는 함수 포인터라면 argument_typeA1이고, T가 인자를 받지 않는 클래스 T0의 멤버 함수 포인터라면 argument_type은 cv 한정이 적용된 T0*이며, T가 멤버 타입 T::argument_type을 가진 클래스 타입이라면 argument_type은 그 별칭이에요.
first_argument_type (C++17에서 deprecated, C++20에서 제거) T가 두 인자 A1A2를 받는 함수 또는 함수 포인터라면 first_argument_typeA1이고, T가 하나의 인자를 받는 클래스 T0의 멤버 함수 포인터라면 first_argument_type은 cv 한정이 적용된 T0*이며, T가 멤버 타입 T::first_argument_type을 가진 클래스 타입이라면 first_argument_type은 그 별칭이에요.
second_argument_type (C++17에서 deprecated, C++20에서 제거) T가 두 인자 A1A2를 받는 함수 또는 함수 포인터라면 second_argument_typeA2이고, T가 하나의 인자 A1을 받는 클래스 T0의 멤버 함수 포인터라면 second_argument_type은 cv 한정이 적용된 A1이며, T가 멤버 타입 T::second_argument_type을 가진 클래스 타입이라면 second_argument_type은 그 별칭이에요.

멤버 함수

멤버 함수 설명
(constructor) std::reference_wrapper 객체에 참조를 저장해요. (public member function)
operator= std::reference_wrapper를 다시 바인딩해요. (public member function)
get, operator T& 저장된 참조에 접근해요. (public member function)
operator() 저장된 함수를 호출해요. (public member function)

비멤버 함수

함수 설명
operator==, operator<=> (C++26) 저장된 참조로 reference_wrapper 객체를 비교해요. (function)

추론 가이드 (C++17 이후)

C++17부터 std::reference_wrapper에 대한 추론 가이드가 제공돼요.

헬퍼 클래스

헬퍼 클래스 설명
std::basic_common_reference<std::reference_wrapper> (C++23) reference_wrapper와 비-reference_wrapper의 공통 참조 타입을 결정해요. (class template specialization)

가능한 구현

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 : // types using type = T ; // construct/copy/destroy 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 ; // assignment reference_wrapper & operator = ( const reference_wrapper & x ) noexcept = default ; // access 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 ; }; // deduction guides 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

같이 보기

함수 설명
ref, cref (C++11) 인자에서 타입을 추론한 std::reference_wrapper를 생성해요. (function template)
bind (C++11) 하나 이상의 인자를 함수 객체에 바인딩해요. (function template)
unwrap_reference, unwrap_ref_decay (C++20) std::reference_wrapper에 감싸인 참조 타입을 가져와요. (class template)

더 알아보기 (Learn more)

cppreference