template <typename T>
void fucn(T&& param)
{
...
}
"param의 형식은 오른값이지만 param자체는 왼값이다"
위의 코드와 문장을 보고 무슨말이신지 이해가 안 가신다면
https://cjbworld.tistory.com/27를 보고 와주시면 감사하겠습니다.
전달 참조란? auto, template 같은 "형식 연역"에서 type deduction 발생시 자주사용하는 개념입니다.
(형식 연역 : 아직은 정해지지 않았지만 컴파일 타임에 때려 맞추겠다)
오른값 참조와 비슷하게 생긴 요녀석은 &&를 같이 사용합니다.
위 코드애서 p1는 lvalue입니다. 컴파일러 경고에 따르면 rvalue참조에다가 lvalue를 넣을 수 없다고 하는군요.
왜냐하면 mp의 형식은 오른값 참조이기 때문에 오른값을 참조할 수 있습니다.
그런데 p1은 현재 왼값이죠.
그래서 아래와 같이 캐스팅을 해주거나 std::move를 사용해 줄 수 있습니다.
Person&& mp = static_cast<Person&&>(p1);
Person&& mp2 = std::move(p1);
그러면 오른값 형식을 받는 TestFunc에 mp를 인수로 전달 할 수 있을까요?
이또한 안됩니다.
mp는 왼값이기 때문입니다. TestFunc의 함수는 현재 "오른값 참조"를 받기때문이기도 합니다.
위의 경우에는 컴파일이 잘 통과되는 모습을 볼 수 있습니다.
그렇다면
Person p1;
p1.name = "Kim";
auto&& ap1 = p1;
auto&& ap2 = std::move(p1);
위의 경우 ap1은 오른값이 아닐까? 라고 생각이 들 수 있지만 ap1은 왼값이고
ap2는 오른값입니다.
즉, 전달 참조는 왼값을 넣어주면 왼값으로 동작하고 오른값을 넣어주면 오른값으로 동작합니다.
void testFunc(Person p)
{
}
template <class T>
void func(T&& param)
{
testFunc(param);
};
int main()
{
ios_base::sync_with_stdio(NULL);
cin.tie(NULL);
cout.tie(NULL);
Person p1("kim");
func(std::move(p1));
return 0;
}
위의 소스코드를 실행하게 되면은 오른값으로 func에 넘겨준 p1이 func안에서 다시 testFunc로 전달되는데
이때 func의 param자체는 왼값이기 때문에 testfunc로 전달시 복사 생성자가 호출됩니다.
하지만 testFunc에도 복사 생성방식이 아니라 이동생성 방식으로 전달하고 싶은경우
template <class T>
void func(T&& param)
{
testFunc(std::move(param));
};
이런식으로 한번더 캐스팅 해주어야합니다.
이런 번거로움이 있기 때문에 std::forward라는 전달참조 방식을 사용할 수 있습니다.
void testFunc(Person p)
{
}
template <class T>
void func(T&& param)
{
testFunc(std::forward<T>(param));
};
int main()
{
ios_base::sync_with_stdio(NULL);
cin.tie(NULL);
cout.tie(NULL);
Person p1("kim");
func(p1);
func(std::move(p1));
return 0;
}
따라서 위 처럼 forward를 사용하여 왼값 오른값을 알아서 구분해줄 수 있게 만들 수 있습니다.
이상 전달참조의 극히 기본인 부분이였습니다 :)
'CPP' 카테고리의 다른 글
[C++] 헤더파일의 의미와 Build Process (0) | 2023.08.10 |
---|---|
[C++] stream buffer와 표준 입출력 (0) | 2023.08.02 |
[C++] 오른값 참조 (0) | 2023.07.30 |
[C++] Effective C++ 항목 1~27 정리 (0) | 2023.07.03 |
[C++] C++ 컴파일 의존성 (2) | 2023.05.28 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!