Chapter 2. auto
5. Prefer auto to explicit type declarations
먼저 auto를 통해서 얻을 수 있는 이점은 다음과 같습니다.
[초기화]
선언만 하고 초기화를 하지 않은 경우를 방지 가능합니다
int x1; // 문맥에 따라 위험함
auto x2; // 오류
auto x3 = 0; // 양호함
[복잡한 이름의 간략화]
C++14의 경우는 형식 뿐만 아니라 람다 표현식의 매개변수에도 auto를 적용시켜 사용 가능하여 코드가 간략화됩니다.
auto derefLess = [](const auto& p1, const auto& p2)
{ return *p1 < *p2; };
또한 반복적인 변수 타입을 적는 것을 방지할 수 있습니다. 특히, std::function을 통한 구현과 auto를 통한 클로저의 구현에서, auto의 경우는 클로저에 요구되는 만큼의 메모리만을 사용하지만, std::function의 경우에는 std::function 템플릿의 한 인스턴스이며 크기가 고정되어 있는데 이 크기가 부족한 경우에는 따로 힙 메모리를 할당하여 클로저를 저장합니다. 결과적으로 대체로 std::function 객체는 auto로 선언된 객체보다 메모리를 더 많이 소비하며, 인라인화 제한 및 간접 함수 호출을 산출하기 때문에 더 느립니다.
또 다른 장점으로는 포인터나 size_type의 반환 값을 받을 때 이를 부호 없는 정수 형식으로 받게 되면, 32비트 Window에서는 돌아가는 것이 64비트 Window에서 돌아가지 않을 수 있습니다. 즉 이러한 환경 변화에도 훨씬 유연한 편입니다.
또한 아래 코드와 같이 코드 형식의 불일치로 인해 불필요한 변환(std::pair<const std::string, int>에서 const std::pair<std::string, int>로의 변환이 필요함)을 만들어 낼수 있지만, auto를 사용하면 이러한 일이 없어집니다.
std::unordered_map<std::string, int> m;
...
for (const std::pair<std::string, int>& p : m) // std::pair<const std::string, int>&가 되어야 함
{
...
}
이것만은 잊지 말자!
- auto 변수는 반드시 초기화해야 하며, 이식성 또는 효율성 문제를 유발할 수 있는 형식 불일치가 발생하는 경우가 거의 없으며, 대체로 변수의 형식을 명시적으로 지정할 때보다 타자량도 더 적다.
- auto로 형식을 지정한 변수는 항목 2와 항목 6에서 설명한 문제점들을 겪을 수 있다.
6. Use the explicitly typed initializer idiom when auto deduces undesired types
대체로 대리자 클래스(proxy class)의 경우는 기저에 다른 클래스가 존재하여 auto의 형식 연역이 예상과는 다르게 돌아갑니다. 그런 클래스는 해당 객체의 수명이 한 문장 이상으로 연장되지는 않는다는 가정하에서 설계되는 경우가 많으며, 따라서 그런 형식의 변수를 생성하는 것은 라이브러리 설계의 근본적인 가정들을 위반하는 경향이 있습니다. 아래의 코드에서 이를 설명합니다.
std::vector<bool> features(const Widget& w);
bool highPriority = features(w)[5]; // 기존 코드
auto highPriority = features(w)[5]; // 미정의 행동
// std::vector<bool>::reference에 의존
auto highPriority = static_cast<bool>(features(w)[5]); // bool로 명시
std::vector<bool>의 경우는 bool당 1비트의 압축된 형태를 표현하도록 명시되어 있어, std::vector<bool>::reference 객체를 통해 표현하는데, auto로 값을 받아오게 되면, 이 객체를 그대로 들고 오게 되면서 다음 행동이 미정의 행동이 됩니다. 따라서 이를 해결하기 위해서는 static_cast와 같이 auto가 다른 형식을 연역하도록 강제해야 합니다. 또한, 이렇게 강제를 하면, 코드를 읽는 사람에게 확실하게 보여주기 때문에 코드의 흐름을 읽기 쉬워집니다.
이것만은 잊지 말자!
- "보이지 않는" 대리자 형식 때문에 auto가 초기화 표현식의 형식을 "잘못" 연역할 수 있다.
- 형식 명시 초기치 관용구는 auto가 원하는 형식을 연역하도록 강제한다.