// int& => int 타입의 lvalue만 전달할 수 있다.
void f1(int& arg) {}
// int&& => int 타입의 rvalue만 전달할 수 있다.
void f2(int&& arg) {}

// T 자체가 참조(& or &&)를 포함하고 있다면, reference collapsing 규칙을 적용.
// T의 뒤쪽에 & 한 개가 붙어 있으므로 T가 어떤 참조로 와도 lvalue 이다.
template<class T> void f3(T& arg) {}

// 
template<class T> void f4(T&& arg) {}

int main()
{
	int n = 0;
	f1(n); // ok
	f1(0); // error
	
	f2(n); // error
	f2(3); // ok
	
	f3(n); // ok
	f3(0); // error

	f4<int>(0); // T=int T&&=int&& f4(int&& arg)
	f4<int&>(n); // T=int& T&&=int& && f4(int& arg)
	f4<int&&>(3); // T=int&& T&&=int&& && f4(int&& arg)

	// forwarding reference, lvalue, rvalue 모두 전달 할 수 있다.
	f4(n); // T=int& f4(int& arg)
	f4(0); // T=int f4(int&& arg)
}

Universal vs Forwarding

lvalue 와 rvalue 모두 받을 수 있는 함수 만들기

Untitled

void foo(int arg) {}
void foo(const int& arg) {}
void foo(int& arg) {}
void foo(int&& arg) {}
template<class T> void foo(T&& arg) {}