KoreanFoodie's Study
Effective Modern C++ | 항목 33 : std::forward 를 통해 전달할 auto&& 매개변수에는 decltype 을 사용하라 본문
Tutorials/C++ : Advanced
Effective Modern C++ | 항목 33 : std::forward 를 통해 전달할 auto&& 매개변수에는 decltype 을 사용하라
GoldGiver 2022. 10. 26. 10:05
C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!
항목 33 : std::forward 를 통해 전달할 auto&& 매개변수에는 decltype 을 사용하라
핵심 :
1. std::forward 를 통해 전달할 auto&& 매개변수에는 decltype 을 사용하라.
C+14 에서 가장 고무적인 기능은 일반적 람다(generic lambdas), 즉 매개 변수에 auto 를 사용하는 람다이다. 예시를 보자.
auto f = [](auto x) { return normalized(x); };
위 람다가 산출하는 클로저 클래스의 함수 호출 연산자는 다음과 같을 것이다.
class 컴파일러가_만든_이름 {
public:
template<typename T>
auto operator()(T x) const
{ return normalized(x); }
};
위의 람다는 normalized 에 항상 왼값(매개변수 x) 만을 전달한다. 그런데 만약 위의 람다가 왼값과 오른값을 다르게 처리한다면 위 코드를 어떻게 고쳐야 할까?
auto f = [](auto&& x)
{ return normalized(std::forward<???>(x)); };
완벽 전달을 사용하면 될 것 같지만, 템플릿 형식으로 사용하는 T 가 없으므로, 위의 방식으로 수정할 수는 없다. 이 때, decltype 을 사용하면 문제를 해결할 수 있다(decltype 의 설명은 항목 28 참고).
auto f = [](auto&& x)
{ return normalized(
std::forward<decltype(x)>(x));
};
decltype(x) 는 x 가 왼값이면 왼값 참조를, x 가 오른값이면 오른값 참조를 산출한다. 그런데 사실 x 가 오른값일 경우, decltype 은 오른값 참조가 아닌 비참조를 산출해야 한다. 하지만 항목 28 에 나온 std::forward 의 템플릿 형식 함수에 Widget 과 Widget&& 을 넣은 결과는 동일하므로, decltype(x) 는 오른값 참조 형식을 산출하게 된다.
임의의 매개변수들을 받아 완벽하게 전달하는 함수를 만드려면, 마침표 세 개만 추가하면 된다.
auto f = [](auto&&... xs)
{ return normalized(
std::forward<decltype(xs)>(xs)...);
};
'Tutorials > C++ : Advanced' 카테고리의 다른 글
Effective Modern C++ | 항목 35 : 스레드 기반 프로그래밍보다 과제 기반 프로그래밍을 선호하라 (0) | 2022.10.26 |
---|---|
Effective Modern C++ | 항목 34 : std::bind 보다 람다를 선호하라 (0) | 2022.10.26 |
Effective Modern C++ | 항목 32 : 객체를 클로저 안으로 이동하려면 초기화 갈무리를 사용하라 (0) | 2022.10.26 |
Effective Modern C++ | 항목 31 : 기본 갈무리 모드를 피하라 (0) | 2022.10.26 |
Effective Modern C++ | 항목 30 : 완벽 전달이 실패하는 경우들을 잘 알아두라 (0) | 2022.10.26 |
Comments