[C++11] std::array

C++11에서는 STL에 array라는 새로운 컨테이너를 추가 하였습니다. vector 컨테이너와 유사하지만 다음과 같은 차이가 있습니다.

  • vector는 heap을 사용하지만 array는 stack을 사용함
  • vector는 크기가 유동적이지만 array는 크기가 고정임
  • vector보다 array가 item 접근 속도가 빠름

이 array 컨테이너 클래스에 대한 가장 기본적은 사용은 다음과 같습니다.

#include "stdafx.h"
#include 
#include 

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    array arr = {1, 2, 3};

    for(auto i = arr.begin(); i != arr.end(); ++i) {
        cout << *i << endl;
    }
	
    return 0;
}

9번 코드에서 보듯이 array는 타입과 배열의 크기를 갖습니다. 예제에서는 크기를 10으로 지정했는데 실제값은 3개만을 지정하고 있습니다. 이렇게 될 경우 나머지 7개에 대해서는 0의 값으로 채워집니다. 11번 코드는 일반적인 STL의 컨테이너 요소를 순회하며 접근하는 코드를 볼 수 있습니다. array는 vector와 마찬가지로 []를 통해 요소에 접근할 수 있으며 다음 예과 같습니다.

#include "stdafx.h"
#include 
#include 

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    array arr = {1, 2, 3};
	
    cout << "size: " << arr.size() << endl;
    cout << arr[0] << " " << arr[1] << " " << arr[2] << " ..." << endl;

    return 0;
}

C++11에서의 array는 원래의 배열인 C-Array 타입과 전혀 호환되지 않습니다. C++11의 array를 C-Array로의 타입 변환을 위해서는 다음과 같은 예를 통해 가능합니다.

#include "stdafx.h"
#include 
#include 

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    array arr = {1, 2, 3};

    int *pArr = arr.data();
    pArr[1] = 100;
    cout << arr[0] << " " << arr[1] << " " << arr[2] << " ... " << endl;

    return 0;
}

C-Array 타입으로 변환되었을지라도 12번 코드처럼 값을 변경하면 C++11에서의 array 객체에도 적용되는 것을 알 수 있습니다. 이것으로 볼때 C++11의 array는 내부적으로 C-Array를 그대로 사용하는 것을 알 수 있습니다.

[C++11] 유니폼 초기화(Uniform Initializer)

유니폼 초기화는 객체의 초기화를 보다 간단한 코드만으로 구현할 수 있는 기능입니다. 예를 들어 다음과 같은 Product라는 클래스가 있다고 할때 이 Product 클래스의 객체를 초기화하여 생성하는 경우를 예를 들어 보겠습니다.

#include "stdafx.h"
#include 
#include 

using namespace std;

class Product
{
private:
    string name;
    int cost;
public:
    Product(const string& name, int cost) : name(name), cost(cost) {}
};

int _tmain(int argc, _TCHAR* argv[])
{
    Product r("Apple", 100);
	
    return 0;
}

이미 흔히 알고 있는 방식으로 18번 코드와 같이 객체를 초기화하면서 생성하고 있습니다. 이런 초기화 방식에 대해 C++11은 다음과 같은 방식도 지원합니다.

#include "stdafx.h"
#include 
#include 

using namespace std;

class Product
{
private:
    string name;
    int cost;
public:
    Product(const string& name, int cost) : name(name), cost(cost) {}
};

int _tmain(int argc, _TCHAR* argv[])
{
    Product r {"Apple", 100};
	
    return 0;
}

변경된 부분은 15번 코드입니다. 바로 () 대신에 {}를 사용해 초기화를 하고 있습니다. 여기까지는 별 것 없는 것 같습니다만 이러한 초기화 방식이 유니폼 초기화(Uniform Initializer)입니다. 이 별것 없을 것 같은 초기화 방식이 배열이나 콜렉션(Collection, Container)에서는 다음처럼 응용되어 사용할 수 있습니다.

#include "stdafx.h"
#include 
#include 
#include 

using namespace std;

class Product
{
private:
    string name;
    int cost;
public:
    Product(const string& name, int cost) : name(name), cost(cost) {}
};

int _tmain(int argc, _TCHAR* argv[])
{
    vector v {
        {"Apple", 100},
        {"Orange", 200},
        {"Grape", 300}
    };

    return 0;
}

유니폼 초기화를 이용하여 vector 컨테이너에 3개의 객체를 생성하고 있습니다. 이러한 방식을 이용하지 않고 3개의 객체를 초기화하여 컨테이너에 추가하는 기존의 코드를 생각해 본다면 이러한 유니폼 초기화 방식이 얼마나 직관적인지 쉽게 짐작해 볼 수 있습니다.