상세 컨텐츠

본문 제목

[C++11] auto

C++/Modern C++(11, 14, 17, 20)

by deulee 2023. 8. 26. 18:12

본문

`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`의 타입 추론은 대체로 템플릿 타입 추론과 같지만, `auto` 타입 추론은 `{중괄호 초기화}``std::initializer_list`를 나타낸다고 가정하는 반면 템플릿 타입 추론은 그렇지 않다는 차이가 존재한다.

 

`auto` 키워드는 총 3개의 경우를 통해서 타입을 추론하는데 다음과 같다.

  1. 경우 1: 타입 지정자가 포인터나 참조 타입이지만 보편 참조(universal reference)는 아닌 경우.
  2. 경우 2: 타입 지정자가 보편 참조(universal reference)인 경우.
  3. 경우 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++ > Modern C++(11, 14, 17, 20)' 카테고리의 다른 글

[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

관련글 더보기