C++

C++11 auto

차차냥 2023. 2. 16. 02:42

auto 란?

컴파일 단계에서 오른쪽의 데이터를 기반으로 자료형을 추론해서 타입을 알아서 찾아주는 키워드.

C++11 이전에도 존재하던 키워드이나, C++11 부터 선언의 초기화 식에서 형식이 추론되는 변수를 선언하는 역할을 하게 되었다. 때문에 Modern C++ 의 주요 변화 중 하나라고 볼 수 있다. (C++11 부터 Modern C++이라고 칭한다)

찾아보니 C++11 이전에는 자동 저장소 클래스에 있는 변수, 지역변수를 선언하는 역할이었다고 함.

 

auto 예시를 들며 어떤 역할을 하는지 알아 본다.

class Actor
{
public:
	int _hp;
}

// 자료형을 직접 명시했을 때
int a = 4;
float b = 3.14f;
double c = 9.82;
Actor d = Actor();
const char* e = "chacha";

// 컴파일 단계에서 찾아서 자동으로 자료형을 추론해서 찾아주므로 위 아래가 동일.
auto a = 4;
auto b = 3.14f;
auto c = 9.82;
auto d = Actor();
auto e = "chacha";

아래의 Template과 비슷하게 데이터 형태를 추론해주는 형식 연역 (type deduction)이다.

더보기

형식 연역에 대한 정보는 여기서 참조 가능하다
https://narakit.tistory.com/74

template<typename T>
void Print(T t)
{
	cout << t << endl;
}
// 온갖 데이터를 다 넣을 수 있는 template 과 비슷

Print(3); // == Print<int>(3) 과 동일함
Print("chacha"); // == Print<const char*>("chacha") 과 동일함

추론 규칙은 조금 복잡해지기도 한다.

auto 앞에 const 가 붙었을 때, 추론된 데이터 형식 앞에 const 가 붙은 것과 동일한 역할을 하게 해준다.

(But, 강제로 포인터가 되어야 한다고 강제 했을 때, 문법이 맞지 않다고 생각해 오류를 내뱉는 경우 있음. 아래 예시)

auto f = &d;
const auto test1 = b;

// 위의 test1 처럼 auto 앞에 const 가 붙었을 때, 
// 추론된 데이터 형식 앞에 const 가 붙은 것과 동일한 역할을 하게 해준다.

// 문제는..
// 강제로 포인터가 되어야한다고 강제 했을 때
auto* test2 = e; // auto -> const char* test2 가 됨.
auto* test2 = a; // auto -> (int*)? 문법이 맞지 않다고 생각하여 오류를 내뱉음.

자동으로 명시해주니 편하다고 막 쓰기엔, 주의할 점이 있다.

주의 할 점

1. 기본 auto 는 const와 reference(&)는 무시하는 문제가 있다.
2. 식을 추론할 수 없는 경우나, 여러 변수를 넣어 초기화 할 땐 오류를 발생시킨다.
3. auto 키워드는 함수의 매개변수로 쓰일 수 없다.
4. struct, class 등의 멤버 변수에 쓰일 수 없다.

1. 기본 auto 는 const와 reference(&)는 무시하는 문제가 있다.

int& ref = a;
const int cst = a;

auto test1 = ref;
auto test2 = cst;

// auto 만 지정해 놨을 때,
// const 와 &는 떼고 생각한다.. 즉, 위의 test1 과 test2는 아래처럼 인식된다.

////////// 우리가 기대하는 추론되는 자료형 ////////////
int& test1 = ref;
const int test2 = cst;
////////// 실제로 추론되는 자료형 ////////////
int test1 = ref;
int test2 = cst;

2. 식을 추론할 수 없는 경우나, 여러 변수를 넣어 초기화 할 땐 오류를 발생시킨다.

// ###### error! ######
////////// 식을 추론할 수 없는 경우 ////////////
auto test3 = {1, 2.4};

////////// 여러 변수를 넣어 초기화 하는 경우 ////////////
auto test4{3, 4};

3. auto 키워드는 함수의 매개변수로 쓰일 수 없다.

void setName(auto name); // 오류 발생

4. struct, class 등의 멤버 변수에 쓰일 수 없다.

// auto 키워드는 자료형 크기를 정할 수 없어 
// 구조체나 클래스 등의 멤버 변수로 사용 불가 
struct 
{
	auto _hp;
}

class Actor
{
	auto _name;	
}

  • 장점
타이핑이 길고 복잡한 자료형 변수 작성에 사용 시 시간이 단축되는 편리함을 가지고 있다.
아래의 예시처럼, vector<int>::iterator를 대신해서 사용이 가능
map<int, int> m;
auto result = m.insert(make_pair(1,2));

/////// iterator 를 썼을 때
for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
	count << *it << endl;
}

/////// iterator 의 타입을 굳이 보지 않아도 되므로 편리하게 auto 로 대체 가능
for(auto& it = v.begin(); it != v.end(); ++it)
{
	count << *it << endl;
}
  • 단점
auto 의 남발은 자료형을 파악하기 어려워 가독성이 현저히 낮아진다.
또, 무지성으로 쓰게 되는 auto 는 자칫 위의 문제를 초래할 수 있으므로 주의해야 한다.

 auto를 남발하게 될 경우 가독성이 현저하게 낮아지는 단점이 있으나, 길고 복잡한 자료형을 간편하게 쓸 수 있는 무시할 수 없는 장점이 있다. 기본 자료형의 경우 되도록 기존의 타입을 명시해서 가독성을 올리고, 너무 긴 자료형의 경우에 auto를 사용하는 습관을 길들이면 팀원과 미래의 나를 위해 큰 도움이 될 것 같다!

 

여기서 나는 auto의 남발 시 성능에 문제가 생기지 않을까? 라는 의문이 들었다. (처음 auto 를 접했을 때, 이렇게 편하게 추론해주는 문법을 많이 쓰면 게임 성능에 영향이 가지 않을까 싶어 일부러 자료형을 명시하려고 애썼던 기억이..)
검색 결과, auto 는 컴파일 타임에 결정되기 때문에 게임의 실행 속도와는 상관이 없고 대신 컴파일 속도가 정말 미세하게 느려질 가능성이 있음을 알게 된 이후로 아주 잘 쓰고 있다 ㅎㅎ

 

무지성으로 쓰지 말아야 함을 다시 한 번 더 깨닫는다.

 

'C++' 카테고리의 다른 글

[C++] 둘이 뭐가 다른데? Enum vs Enum class  (0) 2023.12.22