Search

C++ | 함수 템플릿의 리턴 타입 추론

Date
2024/10/16
category
C++
Tags
c++

1. auto 리턴

template<typename L, typename R> ReturnType getSum(const L& left, const R& right) { return left + right; }
C++
복사
두 인자의 합을 반환하는 getSum 템플릿 함수가 있다. getSum의 반환 타입인 ReturnTypeleft + right가 반환하는 값의 타입이 돼야 한다. 하지만 getSum은 함수 템플릿이기 때문에 파라미터 타입에 따라 ReturnType이 바뀐다. 모든 타입에 대해 일반화하기 위해선 getSum의 반환 타입을 어떻게 명시해야 할까?
template<typename L, typename R> auto getSum(const L& left, const R& right) { return left + right; }
C++
복사
리턴 타입에 auto 키워드를 사용하면 컴파일러가 리턴 타입을 추론한다. C++14부터 컴파일러가 함수의 리턴 타입을 추론할 수 있다. 이때 주의할 점은 auto 키워드로 타입을 추론할 땐, const와 레퍼런스가 사라진다. 따라서 반환 값의 복사본을 전달한다. 만약 레퍼런스 타입으로 반환해야 하는 경우 이 방법은 최선이 아니다.

2. decltype(auto) 리턴

template<typename L, typename R> decltype(auto) getSum(const L& left, const R& right) { return left + right; }
C++
복사
decltype의 경우 const와 레퍼런스를 유지한다. decltype(auto)decltype(left + right)로 취급한다고 생각하면 된다.
// decltype(getSum(left, right)) sum = getSum(left, right); 동일 decltype(auto) sum = getSum(left, right);
C++
복사
이것은 함수 리턴 뿐만 아니라 변수 초기화 시 타입 추론에도 사용 가능하다.

3. 후행 리턴 타입

함수 리턴 타입 추론 기능은 C++14부터 지원한다고 했다. C++14 이전인 C++11에서 함수 템플릿의 리턴 타입 추론을 구현하려면 어떻게 해야할까?
template<typename L, typename R> decltype(left + right) getSum(const L& left, const R& right) { return left + right; }
C++
복사
auto 키워드 대신 decltype(return 표현식)을 생각해볼 수 있을 것이다. 하지만 이 방법은 컴파일 오류가 발생한다. decltype 내에 있는 leftright는 정의되기 전이기 때문에 컴파일러가 식별할 수 없다.
template<typename L, typename R> auto getSum(const L& left, const R& right) -> decltype(left + right) { return left + right; }
C++
복사
후행 리턴 타입(trailing return type)이라는 것을 활용하면 이 문제를 해결할 수 있다. decltype 내에 있는 leftright는 정의된 후에 사용되기 때문에 컴파일러가 식별 가능하다. 또한 리턴 타입은 자동으로 추론되는 것이 아닌 decltype의 결과를 사용한다. decltype 내의 표현식을 잘못 입력하면 함수의 리턴 타입이 잘못 될 수 있기 때문에 주의가 필요하다.

4. 참고 자료

전문가를 위한 C++ 5판, 12.3.4 함수 템플릿의 리턴 타입, 663p ~ 665p