강의 보고 공부한 것을 정리하는 목적으로 작성된 글이므로 틀린 점이 있을 수 있음에 양해 부탁드립니다. (피드백 환영입니다)
C++11의 신규문법 auto
를 배워볼 것이다!
C++은 다른 언어와 다르게 평생 공부를 해야하는 언어이다.
솔직히 언어는 하나만 제대로 공부를 하는게 훨씬 효율이 좋다.
C#은 별로 어려운 문법이 없기에 빠르게 배우지만 C++은 좀 악랄하다.
C++은 계속 버전이 추가가 되면서 문법이 생겨나고 있다.
우리가 지금 배우고 있는 것은 대부분 C++03이고 C++11부터 Modern C++이라고 하는데 엄청난 대격변이 일어났다.
그리고 C++20에서도 대격변이 일어났지만 아직 연구도 되야하고 전파가 되려면 시간이 걸릴 것이다.
C++11에서는 auto
, lambda
, 범위 기반 for
등이 나왔는데 이것들이 작업속도 향상에 엄청나게 도움을 준다.
그래서 오늘은 첫 스타트로 auto에 대해서 알아볼 것이다.
복습을 해보면 우리가 변수를 사용할 때 메모리를 할당하여서 사용하였다.
class Knight
{
};
int main()
{
int a = 3;
float b = 3.14f;
double c = 1.23;
Knight* d = new Knight();
const char* e = "Rookiss";
}
이런식으로 사용하였었다.
그런데 우리가 auto
를 사용하면
class Knight
{
};
int main()
{
auto a = 3;
auto b = 3.14f;
auto c = 1.23;
auto d = new Knight();
auto e = "Rookiss";
}
이런식으로 사용을 하여서 빌드를 한다면 아무런 문제가 없이 빌드가 된다.
즉, 우리가 일일이 타입을 지정해줄 필요없이 알아서 타입을 지정해주는 것이다.
그러면 어떤 원리로 작동이 되는가? 라고 하면
auto
는 일종의 조커 카드라고 할 수 있다.
저번에 template
을 할때 tamplate
도 조커카드라고하였는데
실제로 template
와 auto
가 사용하는 기술의 뿌리가 비슷하다고 할 수 있다.
template
에서 명시적으로 타입을 나타내지 않아도 알아서 타입을 골라주는 것을
형식 연역(type deduction)
이라고 한다.
형식 연역
은 현재 상황을 보고 그것에 맞는 것을 골라준다는 뜻이다.
즉, 추론을 하는 것이라고 볼 수 있다.
여기서 tmi로 타입이 정해지는 것은 template, auto 모두 컴파일타임에 모두 정해진다.
근데 여기서 추론 규칙이 가끔가다가 복잡해 질 수가 있다.
예를 한 번 들어본다면
auto a = 3;
// a 참조
int& ref = a;
// const int
const int cst = a;
auto ref2 = ref;
auto cst2 = cst;
그럼 과연 ref2와 cst2는 무슨 타입일까?
둘 다 int타입이다.
이것으로 원본타입을 지키지는 않는다는 것을 알 수 있다.
ref는 참조타입이지만 ref2는 참조타입이 아니고 cst는 const타입이지만 cst2는 const타입이 아니다.
그래서 공식처럼 알아야 되는 것중에 하나가 기본적으로 auto는 const, &는 때고 추론을 한다.
그럼 만약에 ref2가 참조타입이길 원한다면 어떻게 해야할까?
그럴때는 auto
뒤에 &를 그대로 붙여주면 된다. auto& ref2 = ref;
이런식으로 말이다.
이렇게 되면 추론을 하는 과정에서 auto는 조커카드이지만 ref가 int의 참조타입이기 때문에 auto
를 int로 바꿔주면 되겠네? 라고 해서 최종 결과물이 int의 참조값이 된다.
그럼 const도 똑같이 const auto cst2 = cst;
이런식으로 해주면 된다.
그럼에도 모든걸 auto가 맞춰주진 않을 수 있다.
auto a = 3;
int* ptr = a;
이런식으로 말이 안되는 것은 오류를 띄운다.
그래서 문법적으로 말이 되는 선에서 사용해줘야 한다.
어차피 const는 사용할 일이 별로 없을 것이고 &이거 붙이는 것만 신경을 써주면 될 것이다.
vector<int> v{1, 2, 3, 4, 5};
for(int ui = 0; i < v.size(); i++)
{
// X 이렇게하면 복사여서 값이 바뀌지 않음
//auto value = v[i];
auto& value = v[i];
if(value == 3)
{
value = 10;
}
}
이런일이 있을 수도 있기 때문이다.
물론 auto고급
으로 가면 더 내용이 복잡해진다.
거기서는 함수 리턴타입도 auto
로 지정해줄 수 있다.
하지만 당장은 이런식으로 사용을 해주면 될 것이다.
auto를 사용하면서의 장단점을 알아보자
auto의 장점!
✨타이핑할 때 굉장히 편하다.
그래서 우리는 이제 iterator
를 사용할 때 auto
로 사용하면 된다!!!
vector<int> v;
auto it = v.begin();
어차피 v.begin()
만 봐도 애가 itrator
인 것을 다 알 수 있다.
그리고 우리가 나중에 map
도 공부를 할 것인데 map
으로가면 더 늘어난다..
map<int, int> m;
std::map<int, int>::iterator it = m.begin();
이걸 다쳐야 하는데... 이것을 다 칠 필요가 없기때문에 그냥
map<int, int> m;
auto it = m.begin();
뿅!! 이런식으로 사용해주면 된다!!
auto의 단점!
😒가독성이 좋지않다.
원래 c#, c++에서는 컴파일을 할 때 타입을 확인할 수 있어서 실수를 줄일 수 있다.
그래서 auto [변수명]
이런식으로 사용하는 것은 추천을 하지 않는다. (성능적으로 차이가 나진 않는다)
그래서 일반적으로 변수를 선언할 때는 타입을 지정해주지만!
iterator
라거나 타입 자체가 타이핑하기 애매할 때(template이랑 묶어서 사용할 때) 사용하는 것을 고려해볼 수 있다!
아 마지막으로 auto
는 함수의 매개변수, 구조체나 클래스의 멤버변수로 사용이 불가하다!