1. auto 리턴
template<typename L, typename R>
ReturnType getSum(const L& left, const R& right)
{
return left + right;
}
C++
복사
두 인자의 합을 반환하는 getSum 템플릿 함수가 있다. getSum의 반환 타입인 ReturnType은 left + 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 내에 있는 left와 right는 정의되기 전이기 때문에 컴파일러가 식별할 수 없다.
template<typename L, typename R>
auto getSum(const L& left, const R& right) -> decltype(left + right)
{
return left + right;
}
C++
복사
후행 리턴 타입(trailing return type)이라는 것을 활용하면 이 문제를 해결할 수 있다. decltype 내에 있는 left와 right는 정의된 후에 사용되기 때문에 컴파일러가 식별 가능하다. 또한 리턴 타입은 자동으로 추론되는 것이 아닌 decltype의 결과를 사용한다. decltype 내의 표현식을 잘못 입력하면 함수의 리턴 타입이 잘못 될 수 있기 때문에 주의가 필요하다.
4. 참고 자료
•
전문가를 위한 C++ 5판, 12.3.4 함수 템플릿의 리턴 타입, 663p ~ 665p