`auto` 키워드는 C++11부터 도입된 기능으로, 변수의 타입을 "컴파일러"가 초기화식을 기반으로 자동으로 추론하도록 하는 기능을 제공한다.
예시를 먼저 보도록 하자.
#include <iostream>
int main(void)
{
auto a = 3.14; // double
auto b = 1; // int
auto& c = b; // int&
auto d = {0}; // std::initializer_list<int>
auto&& e = 1; // int&&
auto&& f = b; // int&
auto g = new auto(123); // int*
const auto h = 1; // const int
auto i = 1, j = 2, k = 3; // int, int, int
auto l = 1, m = true, n = 1.61; // error -- `l` deduced to be int, `m` is bool
auto o; // error -- `o` requires initializer
}
우선 위를 보면 궁금한 점이 몇몇 있지만 이는 나중에 다루도록 하겠다.
쨋든, 예시를 보면 초기화 타입에 맞게 알맞게 타입이 추론되는 것을 볼 수 있다.
그리고 이는 가독성을 굉장히 높여주는데 다음의 코드도 보도록 하자.
std::vector<int> v = ...;
std::vector<int>::const_iterator cit = v.cbegin();
// vs
auto cit = v.cbegin();
위의 예제와 같이 코드의 길이를 대폭 줄일 수 있다.
"함수"에서도 `auto` 키워드를 사용하여 리턴 타입을 추론할 수 있다. 하지만 물론 C++11에서는 리턴 타입을 명시적으로 지정해야 하기 때문에 `decltype` 키워드를 사용하여 이를 해결할 수 있다.
template <typename X, typename Y>
auto add(X x, Y y) -> decltype(x + y)
{
return x + y;
}
add(1, 2); // == 3
add(1, 2.0); // == 3.0
add(1.5, 1.5); // == 3.0
위의 예제에서는 이전에 배운 "trailing return type"과 `decltype`을 이용하여 예시를 작성해보았다.
`auto`의 타입은 `decltype`에 의해 추론된 타입으로 결정되게 된다. 즉, `(x + y)` 표현식에 의해 추론된다는 것이다.
`auto`의 타입 추론은 대체로 템플릿 타입 추론과 같지만, `auto` 타입 추론은 `{중괄호 초기화}`가 `std::initializer_list`를 나타낸다고 가정하는 반면 템플릿 타입 추론은 그렇지 않다는 차이가 존재한다.
`auto` 키워드는 총 3개의 경우를 통해서 타입을 추론하는데 다음과 같다.
#include <iostream>
// 경우 1 : 타입 지정자가 포인터나 참조 타입이지만 보편 참조(universal reference)가 아닌경우
// 경우 2 : 타입 지정자가 보편 참조(universal reference)인 경우
// 경우 3 : 타입 지정자가 포인터도 아니고 참조도 아닌 경우.
int main(void)
{
// `int`
auto x = 13; // 경우 3 -- x는 포인터도 아니고 참조도 아님
// `const int`
const auto cx = x; // 경우 3 -- cx는 포인터도 아니고 참조도 아님
// `const int&`
const auto& rx = x; // 경우 1 -- rx는 보편 참조(universal reference)가 아닌 참조
// `int&`
auto&& uref1 = x; // x는 `int`이자 lvalue이므로 uref1의 타입은 `int&`
// `const int&`
auto&& uref2 = cx; // cx는 `const int`이자 lvalue이므로 uref2의 타입은 `const int&`
// `int&&`
auto&& uref3 = 27; // 27은 `int`이자 rvalue이므로 uref3의 타입은 `int&&`
}
이로써 맨 처음에 생긴 의문이 어느정도는 해결되었다.
이런 타입 추론에 관련해서는 나중에 "Modern Effective C++"이라는 책을 통해 더 자세하게 작성하도록 하겠다.
우선은 `auto`라는 키워드가 있고 어떻게 사용하는지 아는 것에 만족하자.
[C++11] Initializer lists (0) | 2023.08.28 |
---|---|
[C++11] Static Assertions (0) | 2023.08.26 |
[C++11] Lamda Expressions (0) | 2023.08.26 |
[C++11] decltype (0) | 2023.08.26 |
[C++11] Type aliases (0) | 2023.08.26 |