Quick Syntax
auto는 초기화 식에서 타입을 추론하지만, 최상위 const와 참조는 기본형에서 빠집니다. 원본을 빌려 쓸 때는 auto& 또는 const auto&를 명시합니다.
#include <string>
#include <vector>
auto count = 42; // int
auto ratio = 3.14; // double
auto name = std::string{"Mina"}; // std::string (값)
const std::string source{"RefDock"};
auto copy = source; // std::string: const와 참조가 빠진 값 복사
const auto& view = source; // const std::string&: 원본을 읽기 전용으로 빌림
std::vector<int> values{1, 2, 3};
auto it = values.begin(); // 긴 iterator 타입을 추론auto는 긴 iterator·람다·템플릿 결과를 받을 때 특히 유용합니다. 반환 타입이나 수명 계약이 API의 일부라면 auto만으로 감추지 말고 auto&, decltype(auto), 명시 타입 중 의도를 드러내는 형태를 고릅니다.
문법
먼저 다시 보는 기본형은 아래입니다.
- 단순 추론:
auto x = expr; - 참조 유지:
auto& x = expr; - 읽기 전용 참조:
const auto& x = expr; - 타입 보존:
decltype(expr)
auto의 추론 규칙 — 참조와 const는 떨어진다
auto는 오른쪽 표현식에서 타입을 추론하되, 참조와 최상위 const는 기본적으로 제거됩니다. 참조나 const를 유지하려면 auto&, const auto&처럼 직접 명시해야 합니다.
const int ci = 10;
auto a = ci; // int — const 제거됨
auto& b = ci; // const int& — 참조 추가, const 유지
const auto c = ci; // const int — const 명시
std::vector<int> v{1, 2, 3};
auto copy = v; // vector<int> 복사 (새 객체)
auto& ref = v; // vector<int>& (원본 참조)std::string name = "Mina";
auto a = name; // 복사
auto& b = name; // 참조
b += "!"; // name도 같이 바뀜같은 auto라도 & 하나 차이로 의미가 완전히 바뀝니다. "편하게 쓰는 타입 생략"이 아니라 "복사인지 참조인지 먼저 읽는 문법"으로 봐야 합니다.
auto가 빛나는 상황 — 반복자와 범위 기반 for
타입 이름이 길거나 컴파일러만 알 수 있는 경우(lambda, 반복자 등)에 auto가 코드를 크게 단순화합니다.
std::map<std::string, std::vector<int>> data;
// ❌ 타입 전체 명시
std::map<std::string, std::vector<int>>::iterator it = data.begin();
// ✅ auto로 단순화
auto it = data.begin();
// 범위 기반 for — 복사 vs 참조 선택
for (auto item : data) { ... } // pair 복사 (비용)
for (auto& item : data) { ... } // 수정 가능 참조
for (const auto& item : data) { ... } // 읽기 전용 참조 (권장)decltype — 표현식의 타입을 그대로 얻기
auto는 const/참조를 제거하는 반면, decltype은 표현식의 타입을 정확하게 그대로 반환합니다. 주로 템플릿이나 반환 타입 추론에 사용됩니다.
int x = 10;
int& r = x;
auto a = r; // int — 참조 제거
decltype(r) b = r; // int& — 참조 그대로 유지
// 함수 반환 타입 추론 (C++14)
auto add(int a, int b) -> int { return a + b; }
// decltype(auto) — 반환값 타입을 정확히 전달
decltype(auto) get_ref(std::vector<int>& v, int i) {
return v[i]; // int& — 참조 유지
}체크포인트
- 긴 타입 이름 생략:
auto - 원본 참조 유지:
auto& - 복사 없이 읽기:
const auto& - 타입을 정확히 그대로 가져오기:
decltype(expr) - 반환 타입 보존:
decltype(auto)
주의할 점
auto로 컨테이너를 받으면 복사가 발생합니다. 의도치 않은 복사를 막으려면 auto& 또는 const auto&를 씁니다.
std::vector<int> big_vec(1000000, 1);
auto copy = big_vec; // ❌ 100만 원소 복사 — 의도했나?
auto& ref = big_vec; // ✅ 참조 — 복사 없음
const auto& view = big_vec; // ✅ 읽기 전용 참조
// 범위 for에서도 동일
for (auto item : big_vec) { } // ❌ int 복사 (작아서 문제 없지만 습관)
for (const auto& item : big_vec) { } // ✅ 참조
// auto로 문자열 리터럴 받으면
auto s = "hello"; // const char* — std::string 아님!
auto str = std::string{"hello"}; // ✅ std::string// ❌ initializer_list 쪽으로 추론될 수 있어 의도와 다른 타입이 된다
auto values = {1, 2, 3}; // std::initializer_list<int>
// ✅ vector가 필요하면 타입을 분명히 적는다
std::vector<int> values_ok{1, 2, 3};참고 링크
1 sources