[Modern Effective C++] 2. auto의 타입 추론 규칙을 숙지
Updated:
auto 추론 방식
auto의 타입추론은 [1. 템플릿 타입 추론 규칙을 숙지]에서와 같이 템플릿 타입 추론과 거의 같다.
template <typename T>
void f(ParamType param);
auto에서 타입 추론이 이뤄질 때, auto는 템플릿의 T와 동일한 역할을 하며, 변수의 형식 지정자(type specifier)는 ParamType과 동일한 역할을 한다.
auto x = 27;
const auto cx = x;
const auto& rx = x;
template <typename T>
void func_for_x(T param); // x의 타입 추론을 위한 개념적인 템플릿
func_for_x(27);
template <typename T>
void func_for_cx(const T param); // cx의 타입 추론을 위한 개념적인 템플릿
func_for_cx(x);
template <typename T>
void func_for_rx(const T& param); // rx의 타입 추론을 위한 개념적인 템플릿
func_for_rx(x);
템플릿 타입 추론과 마찬가지로 auto의 타입 추론 또한 변수의 형식 지정자에 따라 세가지 경우로 나뉜다.
- ParamType이 포인터 또는 참조 형식이지만 Universal Reference는 아닌 경우
- ParamType이 Universal Reference인 경우
- ParamType이 포인터도 아니고 참조도 아닌 경우
auto x = 27; // 경우 3
const auto cx = x; // 경우 3
const auto& rx = x; // 경우 1
//경우 2
auto&& uref1 = x; // x는 int이고 왼값, uref1의 타입은 int&
auto&& uref2 = cx; // cx는 const int이고 왼값, uref1의 타입은 const int&
auto&& uref3 = 27; // 27은 int이고 오른값, uref3은 int&&
배열과 함수 이름이 포인터로 붕괴는 방식은 auto 또한 동일하다.
템플릿 타입 추론과 차이점
auto x1 = 27; // 타입은 int, 값은 27
auto x2(27); // 위와 동일
auto x3 = { 27 }; // 형식은 std::initializer_list<int>, 값은 { 27 }
auto x4{ 27 }; // 타입은 int, 값은 27
auto는 = 다음에 오는 변수의 초기치가 중괄호 쌍으로 감싸인 형태로 오면 타입 추론은 std::initializer_list로 한다.
그러나 템플릿 함수 인자에 중괄호 초기치를 전달하면 타입 추론이 실패해서 컴파일이 되지않는다.
auto x = { 11, 23, 9 }; // x의 형식은 std::initializer_list<int>
template<typename T>
void f(T param);
f({ 11, 23, 9}); // 오류 T에 대한 타입 추론을 할 수 없음
template<typename T>
void f(std::initializer_list<T> initList);
f({ 11, 23, 9}); // 이건 가능, T는 int로 추론되며, initList는 std::initializer_list<int>로 추론
C++14에서는 함수의 반환 형식을 auto로 지정해서 추론하게 할 수 있으며, 람다의 매개변수에도 auto를 사용이 가능하다.
그러나 이러한 용법은 템플릿 타입 추론이 적용되서 중괄호 초기치를 반환하는 함수는 텀파일이 실패한다.
auto createInitList()
{
return { 1, 2, 3 }; // 오류 {1,2,3} 타입 추론할 수 없음
}
std::vector<int> v;
auto resetV = [&v](const auto& newValue) { v = newValue; }; // C++14
resetV({1,2,3}); // 오류 {1,2,3} 타입 추론할 수 없음
결론
- auto 타입 추론은 대체로 템플릿 타입 추론과 같지만, 중괄호 초기치에선 다르다.
- 함수의 반환 형식이나 람다 매개변수에 쓰인 auto는 템플릿 타입 추론이 적용된다.