C++ auto

200원짜리개발자·2023년 7월 2일
0

C++

목록 보기
23/39
post-thumbnail

강의 보고 공부한 것을 정리하는 목적으로 작성된 글이므로 틀린 점이 있을 수 있음에 양해 부탁드립니다. (피드백 환영입니다)

C++11의 신규문법 auto를 배워볼 것이다!

C++은 다른 언어와 다르게 평생 공부를 해야하는 언어이다.
솔직히 언어는 하나만 제대로 공부를 하는게 훨씬 효율이 좋다.
C#은 별로 어려운 문법이 없기에 빠르게 배우지만 C++은 좀 악랄하다.

C++은 계속 버전이 추가가 되면서 문법이 생겨나고 있다.
우리가 지금 배우고 있는 것은 대부분 C++03이고 C++11부터 Modern C++이라고 하는데 엄청난 대격변이 일어났다.
그리고 C++20에서도 대격변이 일어났지만 아직 연구도 되야하고 전파가 되려면 시간이 걸릴 것이다.

C++11에서는 auto, lambda, 범위 기반 for 등이 나왔는데 이것들이 작업속도 향상에 엄청나게 도움을 준다.

그래서 오늘은 첫 스타트로 auto에 대해서 알아볼 것이다.

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조커카드라고하였는데

실제로 templateauto가 사용하는 기술의 뿌리가 비슷하다고 할 수 있다.
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를 사용하면서의 장단점을 알아보자

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는 함수의 매개변수, 구조체나 클래스의 멤버변수로 사용이 불가하다!

profile
고3, 프론트엔드

0개의 댓글