C++11에서 auto 키워드가 생겼다. 우리가 기존에 명시해주던 자료형에 대하여 저장하는 데이터 형태를 보고 자료형을 추론해내어 알아서 저장한다. 프로그래밍하면서 굉장히 유용하게 쓸 수 있으니 숙지해두면 좋을 개념이다.


일반적인 변수 초기화

 

일반적으로 하는 변수 초기화를 생각해보자. 변수 이름 앞에 자료형을 기입해주고 초기화해주는 r-value를 해당 자료형에 맞게 입력해준다. 이 경우 해당 변수는 양 옆으로 똑같이 자료형에 대한 정보를 주는 상황이 된다. 즉, 같은 정보가 중복되어서 입력된 것이다. 물론 double로 선언하고 3을 넣는 사람도 있지만 3.0을 넣는게 올바른 프로그래밍이겠다.

#include <iostream>

int main()
{
	using namespace std;

	int a = 123;

	return 0;
}

int 자료형과 r-value 123(int) 정보가 중복되어 들어오는 예시이다.


auto 키워드

 

앞에서 언급한 것처럼 정보가 중복되어 들어오는 것을 비효율적이라 생각하여 auto 키워드가 생겼다. 정보 입력은 하나만 있어도 충분하기 때문이다. auto 키워드를 사용하여 선언을 하는 경우 반드시 초기화도 함께 해주어야 한다. 저장되는 데이터를 컴파일러가 추론해서 어느정도의 메모리를 사용하여 어떤 기본 자료형으로 저장할지 선택해야 하는데, 애초에 저장할 데이터를 안 주면 추론 자체가 불가능하니 당연하겠다.

#include <iostream>

int main()
{
	using namespace std;

	int a = 123;

	auto b = 123123123123123123;
	auto d = 123.0;
	auto c = 1 + 2.0;

	return 0;
}

이렇게 auto로 초기화한 변수에 마우스 커서를 올리면 어떤 자료형으로 추론이 되었는지 알 수 있다.

long long으로 추론되었다.

이렇게 한 번 추론이 되면 추론된 자료형으로 취급하여 다루면 되겠다.


함수에서의 auto 키워드

 

auto 키워드는 함수를 다룰 때도 사용할 수 있다.

int add(int x, int y)
{
	return x + y;
}

int main()
{
	using namespace std;

	auto result = add(1, 2);

	return 0;
}

이처럼 함수에서 return 값을 auto로 받아낼 수 있겠다. 위의 코드에서 add 함수를 아래 두가지로 변경해서 넣어보자.

auto add(int x, int y)
{
	return x + y;
}

auto add(int x, int y)
{
	return x + (double)y;
}

정의부터 auto를 써서 사용한다. 애초에 return에 놓인 결과값도 int이기 때문에 추론이 가능한 형태이다. 두 번째 add 함수는 return하기 전에 double로 형 변환을 수행하였다. 이럴 경우 return 값이 double로 변하고 해당 함수의 return 값을 받아야 하는 변수도 double이 되어야 한다. 전부 auto로 연결되어서 문제없이 작동하는 것을 확인할 수 있다.

 

매개 변수 위치에는 auto 키워드를 쓸 수 없다. 매개 변수에 auto 키워드를 쓰는 목적을 생각해보면 함수 오버로딩을 안 하고 한 번에 정의하기 위함일 듯하다. 그러한 목적을 충족시켜주는 template 개념이 이미 존재하기 때문에 template을 활용하여 사용하면 되겠다.

 

auto 키워드가 생기면서 function trailing return type이라는 개념으로 프로그래밍이 가능해졌다. 결과가 되는 자료형을 아래처럼 함수 뒤에 적는 것이다. 굳이 적을 필요가 있냐는 생각이 들 수 있지만 추후 다루게 될 template과 사용할 때 효과를 발휘한다. 또한 함수의 결과가 무엇인지 좌에서 우로 순차적인 형태가 되기 때문에 C++이 익숙하지 않은 프로그래머에게 가독성을 높이는 코딩이라 할 수 있겠다.

auto add(int x, int y) -> double;

int main()
{
	using namespace std;

	auto result = add(1, 2);

	return 0;
}

auto add(int x, int y) -> double
{
	return x + (double)y;
}

Reference

내가 아는 익숙한 for문과는 for문을 보았기에 이를 기록하려 한다...!


일반적인 for문

 

남들에게는 일반적인 게 아닐 수 있지만 내가 프로그래밍을 하면서 보았던 코드들에서 대부분 for문은 다음과 같은 형태로 구현되어 있었다.

#include <iostream>

using namespace std;

int main()
{
	int arrayTest[10] = { 1,2,3,4,5,6,7,8,9,10 };

	for (int i = 0; i < 10; i++)
	{
		cout << arrayTest[i] << endl;
	}

	return 0;
}

정말 교과서에 나오는 정석적인 for문이다...! 이렇게 생긴 코드를 대부분의 C/C++ 개발자들이 제일 처음 본 반복문이라고 나는 생각한다.


auto 키워드를 활용한 for문

 

주말에 프로그래밍 공부를 조금씩 하다가 발견한 for문이다. 정말 너무 간결하고 nice해서 충격을 먹고 포스팅을 한다.

#include <iostream>

using namespace std;

int main()
{
	int arrayTest[10] = { 1,2,3,4,5,6,7,8,9,10 };

	for (auto element : arrayTest)
	{
		cout << element << endl;
	}

	return 0;
}

for문 첫 줄이 엄청나게 간결해졌다...!! 기존의 for문과 한번 비교 분석을 해보자!

 

우선 첫 번째로 당연히 코드가 간결해지고 코드 작성 시간이 줄어들게 되었다. 이전 코드는 은근히 코드를 작성하면서 기호를 추가하는 경우 끊김이 생기곤 했는데 위처럼 작성하는 경우엔 콜론 하나만 있으니 금방 타이핑을 할 수가 있었다. 두 번째로는 주어진 배열의 길이를 자동으로 for문이 가지게 된다는 점이다. for문을 작성할 때 항상 고민이었던 점은 배열을 사용하는 경우 for문에 해당 배열의 끝 지점이 어디인지 반드시 알고 있어야 했고 이를 잘못 지키는 경우 코드가 제대로 동작하지 않았다. 그래서 항상 어떻게 배열의 길이를 전달해줄까 고민하곤 했는데 이제 이런 고민을 할 필요는 없어졌다.

 

당연히 장점만 있는 것은 아닐 것이다. 바로 직전의 코드처럼 작성한다면 element에 매번 배열의 값이 복사된다. 이는 성능 하락의 주범이 될 수도 있겠다. 언제나 복사는 덜할수록 좋은 것 같다. 그리고 아직 검증은 안 해봤지만 저러한 작성 방식도 openMP가 적용되는지 의문이다. 이건 내일 회사 가서 한번 적용해서 돌려봐야겠다.

 

참고로 복사를 막는 방법으로 구현한 것은 아래와 같다. 참조 연산자를 사용하면 매번 복사하지 않고 수행시킬 수 있게 된다!

#include <iostream>

using namespace std;

int main()
{
	int arrayTest[10] = { 1,2,3,4,5,6,7,8,9,10 };

	for (auto& element : arrayTest)
	{
		cout << element << endl;
	}

	return 0;
}

오랜만에 최신 문물을 접한 느낌으로 충격을 받았다. 기존과 성능 차이가 꽤 있을지는 모르겠지만 적어도 코드가 간결해질 수 있어서 너무 좋은 것 같다. 혹시나 추가 설명이 필요하다면 아래 글을 참고하자!

 

 

Range-based for loop (since C++11) - cppreference.com

Executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container. [edit] Syntax attr(optional) for ( init-statement(optional)range-declaration : range-exp

en.cppreference.com

 

+ Recent posts