On this page
article
std::reference_wrapper
개념
std::reference_wrapper
는 참조를 값처럼 복사하고 전달할 수 있게 만들어주는 래퍼- 내부적으로 포인터를 저장하고, 변환 연산자와
get()
함수를 통해 raw referecne로 암시적 변환 가능 - C++11에서 도입됨
기본 구조
template<typename T>
class reference_wrapper
{
T* pobj{};
public:
reference_wrapper(T& obj) : pobj{&obj} {}
operator T&() const { return *pobj;}
T& get() const { return *pobj;}
};
int main()
{
int n = 10;
reference_wrapper r1{n};
int& r2 = r1;
int& r3 = r1.get();
}
예제
int n = 10;
std::reference_wrapper r1{n};
int& r2 = r1; // 암시적 변환
int& r3 = r1.get(); // 명시적 접근
callable 객체로 사용 가능
operator()
를 재정의한 객체에 대한 참조를 감쌀 경우,reference_wrapper
자체가 함수처럼 호출 가능
int add(int a, int b) { return a + b; }
std::reference_wrapper f{add};
int n = f(1, 2); // f.operator()(1, 2)
생성 방법
int n = 10;
std::reference_wrapper r1{n};
std::reference_wrapper<int> r2{n};
std::reference_wrapper<const int> r3{n};
r1.get() = 20; // ok
r2.get() = 20; // ok
// r3.get() = 20; // error (const)
// 편의 함수 사용
auto r4 = std::ref(n); // r1과 같음
auto r5 = std::cref(n); // r3과 같음
활용
- 값으로 설계된 함수에서 참조를 전달하고 싶을 때 유용함
std::ref
또는std::reference_wrapper
를 사용하면 참조를 값처럼 전달 가능
예제: 참조 전달 유지
void foo(int& r) { r = 100; }
template<typename F, typename T>
void log_and_call(F f, T arg) {
f(arg);
}
int main() {
int n = 0;
log_and_call(foo, std::ref(n)); // n이 수정됨
}
위의 예시와 같은 설계 이유
- call by value로 설계하는 것이 더 안전해서
- bind, ref로 쓰면 파괴되지않게 유의해야 함함