<개인공부>/[C++]

[C++] auto 타입추론에 대해서

사용자 BlockDMask 2019. 12. 14. 01:48
반응형

안녕하세요. BlockDMask 입니다.

오늘은 C++에서 아주 편리하게 사용될 수 있는 auto 키워드에 대해서 알아보려고 합니다.

C++11 이후의 auto에 대해서 이야기 해볼것 입니다.

C++에서 for 반복문에서 auto를 사용하는 방법 iterator에서 auto 사용하는 방법 등 여러 예제로 다뤄 볼 생각 입니다.

그럼 시작하겠습니다.


<목차>

1. C++11 auto 기본 설명 

2. auto에 &, const, const& 등의 한정자가 붙을때


예제들

3. auto 기본 변수 선언시 사용

4. C++ auto for 문에서 사용

5. auto와 vector iterator 등과 사용

6. C++ auto 와 함수포인터




1. C++11 auto 기본 설명


auto 키워드는 C++11 이전에는 다른 의미로 쓰였습니다. 그리고 C++11 이후에 새롭게 태어났습니다. 그러므로 C++11 이전의 auto에 대해서는 몰라도 됩니다.


▶ auto 키워드란?

auto는 부르는 사람에 따라서 조금씩 다르게 불리는데요.

이런식으로 불리곤 합니다.  "타입 추론", "데이터 타입 추론", "자동 데이터 추론", "초기화 값에 따라 알아서 데이터 타입을 정해주는 키워드"

auto 키워드는 선언한 변수나 람다식의 타입을 컴파일러에게 추론하도록 맡깁니다.


정리를 하자면 "auto는 초기화 값에 따라 알아서 데이터 타입을 정해주는 키워드" 입니다.


auto를 사용하면 아래 예제 처럼 변수를 선언할 수 있습니다.

auto a1 = 10;                       // int 타입

auto a2 = 10.0f;                  // float 타입

auto a3 = "c";                      // char 타입

auto a4 = "BlockDMask";    // string 타입

auto a5 = {10, 20, 30};       //int 배열 타입


이런식으로 따로 int, float, char, string ... 등등 앞에 타입을 정해주지 않아도 알아서 변수의 타입을 정해주는 키워드 입니다. 참 편리하죠?

C#의 var와 비슷하다고 생각하면 됩니다.


aut키워드는 컴파일러에 의해서 타입이 추론 (타입 예상)이 되므로 auto 로 선언한 변수 위에 마우스를 가져다 대면 추론한 타입이 나옵니다.




2. auto에 const, const& 한정자가 붙을때


auto를 그냥 사용할 수 있지만 한정자와 함께 사용함으로써 효율을 더 높일 수 있습니다.

(1) auto와 &, * 함께 사용하기

&, *의 특성이 무엇입니까. 복사가 되지않고 주소를 가리키거나 참조를 하는것이죠. 네 맞습니다. 복사가 아닌 것입니다.

이것을 명확하게 표기 하기 위해서 

auto& 

auto* 

이렇게 받아올 수 있습니다. &로 예를 하나 들어보겠습니다.

vector<int> v = {1, 2, 3, 4, 5}; 라는 vector가 있고

이 벡터의 모든 값들을 x2를 해야한다고 할때, 


우리는 for문을 이용해서 아래와 같이 사용할수 있습니다.

for(auto it = v.begin(); it != v.end(); ++it)

{

*it *= 2;

}

이런식으로 auto를 이용해서 vector<int>::iterator 타입을 대신해서 사용할 수 있지만,

&와 range based for문을 이용하면 훨씬 있어보이게 코딩을 할 수 있습니다.

for(auto& elem : v)

{

elem *= 2;

}

바로 이런식으로 말이죠. 어떤가요 훨씬 깔끔해 보이죠?

이런식으로 auto에 참조(reference)를 사용해서 코드를 짤 수 있습니다. 포인터 예제는 따로 작성하지 않겠습니다.

**C++ range based for문에 대해서 알고싶다면? [바로가기]

**누가봐도 명확히 *타입이거나 & 타입인 경우 auto의 타입추론에 의해서 *, &로 받아오긴 합니다. 하지만 명확하게 표현하기 위해서 누가봐도 명확한 경우에도 써주는것을 개인적으로는 추천, 선호 합니다.

(2) auto와 const 함께 사용하기

const auto a = 10;

const auto b = "BlockDMask";

const auto c = 'c';

const auto d = 11.0f;


이런 방식으로 const auto를 사용할 수 있습니다. 이런 경우에는

a같은 경우 const int  타입이 되고,

b같은 경우에는 const std::string 타입이 됩니다.

const의 특징은 다들 잘 알고 계실거라 생각하고 넘어가겠습니다. (이 포스팅 주제는 auto 이기 때문입니다.)

(요약 : const 가 붙으면 상수 취급이라 값을 변경할 수 없습니다.)



(3) auto와 const& 함께 사용하기

const& auto a = 20;

const& auto b = "BlockDMask";

vector<[인자의 메모리 크기가 큰 클래스 등]> v ;

for(const auto& elem : v)

{

//vector의 인자로 들어가 있는 클래스, 변수의 값을 바꿀거는 아니고, 

//값을 이용해서 출력하거나 할때. 복사는 비용이 너무 크니까 const &를 이용하는걸 추천드립니다.

}


위와 같은 방식으로 const& auto를 사용할 수 있습니다. const 만 이용해서 대입을 하다보면 복사 비용이 들기 때문에

상대적으로 복사 비용이 많이 드는 변수,클래스 등은 const& 를 이용해서 사용할 수 있습니다.

a의 타입은 const int&  타입이 될것이고,

b의 타입은 const std::string& 타입이 될 것입니다.




3. auto의 기본 예제들


▶ 기본 데이터 타입들을 auto 키워드로 받았을때 size와 type name들

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<iostream>
#include<vector>
#include<string>
using namespace std;
 
int main(void)
{
    auto a = 10;
    auto b = "BlockDMask";
    auto c = 'c';
    auto d = 11.0f;
    vector<int> v = { 12345 };
    class Student {
        string name;
        int score;
    };
 
    cout << "sizeof(x)\t|x\t\t\t|typeid(x).name()\n" <<endl;        
    cout << sizeof(a) << "\t\t|" << a << "\t\t\t|" << typeid(a).name() << endl;
    cout << sizeof(b) << "\t\t|" << b << "\t\t|"   << typeid(b).name() << endl;
    cout << sizeof(c) << "\t\t|" << c << "\t\t\t|" << typeid(c).name() << endl;
    cout << sizeof(d) << "\t\t|" << d << "\t\t\t|" << typeid(d).name() << endl;
    cout << sizeof(v) << "\t\t|" << "vector" << "\t\t\t|" << typeid(v).name() << endl;
    cout << sizeof(Student) << "\t\t|" << "Class" << "\t\t\t|" << typeid(Student).name() << endl;
    return 0;
}
cs


▷ 예제결과




4. for 문과 auto 예제


▶ for 반복문과 auto 사용예제들

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<iostream>
#include<vector>
#include<string>
using namespace std;
 
int main(void)
{
    cout << "1. int arr[] : ";
    int arr[] = { 10203040506070 };
    //for (int i = 0; i < 7; ++i)
    for (auto i = 0; i < 7++i)
    {
        cout << arr[i] << ", ";
    }
    cout << endl << endl;
 
    cout << "2. vector<int> v : ";
    vector<int> v1 = { 123456789 };
    //for(vector<int>::iterator it = v1.begin; it != v1.end(); ++it)
    for (auto it = v1.begin(); it != v1.end(); ++it)
    {
        cout << *it << ",";
    }
    cout << endl << endl;
 
    cout << "> range based for 사용\n";
    cout << "3. vector<char> v : ";
    vector<char> v2 = { 'B','l','o','c','k','D','M','a','s','k' };
    //for (char elem : v2)
    for (auto elem : v2)    //여기선 const auto& elem 을 써주는걸 추천합니다.
    {
        cout << elem << ",";
    }
    return 0;
}
cs


▷ 예제결과


▶ iterator와 같이 긴 타입을 대신하는 auto !!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<iostream>
#include<vector>
#include<string>
using namespace std;
 
int main(void)
{
    vector<string> v = { "BlockDMask""Blog""Auto""Code""Program""CPP" };
    cout << "vector<string> v : ";
    
    //vector<string>::iterator = v.begin();
    auto it = v.begin();
    for (; it != v.end(); ++it)
    {
        cout << *it << ", ";
    }
    return 0;
}
cs


▷ 예제결과

이렇게 vector<string>::iterator 와같이 긴 타입을 auto 알파벳 네개로 표현을 할수있습니다. (신세계 입니다.)





6. 함수포인터와 auto 예제


▶ auto키워드를 가지고 함수 포인터 sort 함수의 세번째 인자로 

sort 알고리즘 함수 사용법 및 예제 : [바로가기]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
 
//오름차순
bool compareAsc(int a, int b)
{
    return a > b;
}
 
//내림차순
bool compareDes(int a, int b)
{
    return a < b;
}
 
int main(void)
{
    vector<int> v = { 54216107 };
 
    cout << "오름차순 : ";
    auto pFunc = compareAsc;
    sort(v.begin(), v.end(), pFunc);
    for (const auto& elem : v)
    {
        cout << elem << ", ";
    }
    cout << endl;
 
    cout << "내림차순 : ";
    pFunc = compareDes;
    sort(v.begin(), v.end(), pFunc);
    for (const auto& elem : v)
    {
        cout << elem << ", ";
    }
    cout << endl;
 
    return 0;
}
cs


예제결과


1.  auto pFunc의 타입은 pFunc 위에 마우스를 올리면 이와 같이 나옵니다. 

매개변수가 int 타입으로 두개고 반환으로 bool 타입인 함수에 대한 포인터 타입으로 pFunc가 선언되는걸 볼 수 있습니다.


2.  반복문을 사용하는 곳에서는 range based for문을 이용했습니다.

- range based for문 사용법과 예제는 다른 포스팅에 있습니다 : [바로가기]

- for문에서 사용한 auto에는 const와 &가 붙어있는 const auto& elem 으로 사용했습니다.

elem에는 vector의 인자들을 변경하지 않을거기 때문에 const를 사용한것이고 복사하지 않기 위해 &를 사용했습니다.


이렇게 auto가 유용합니다. 여러분.

아무 변수에 사용하는 것은 추천하지 않고 iterator 같이 복잡한 타입이나 for문 등 적절한 곳에서 사용하는 것을 추천합니다.

모던 C++ auto 사용법 포스팅 이것으로 마치겠습니다. 감사합니다.

(range based for문과 auto는 함께 쓰면 매우 편리합니다.)

반응형