본문 바로가기

Programming/CPP11&14

[C++11] 배열을 편리하게 사용할 수 있는 std::array

반응형

배열은 한 번 크기가 정해지면 동적으로 변경되지 않습니다.

동적으로 크기를 변경하려면 벡터 등의 STL 컨테이너를 활용하면 됩니다.

배열을 STL 컨테이너 형태로 사용하는 것이 바로 std::array입니다.

동적인 할당과 해제가 없어서 성능상 이점이 있는 배열을 편리한 사용을 할 수 있도록 해줍니다.

std::array는 <array> 헤더를 포함한 이후에 사용이 가능합니다.

기본적인 std::array의 사용 방법은 다음과 같습니다.

#include <array>
#include <iostream>

int main()
{
	// initialization
	std::array<int, 5> data = {0, 1, 2, 3, 4};

	// get size
	std::cout << "Size: " << data.size() << std::endl;

	// iterator
	for (auto it = data.cbegin(); it != data.cend(); ++it)
	{
		std::cout << *it << " ";
	}
	std::cout << std::endl;

	// get an address of first element
	std::cout << *data.data() << std::endl;

	// C-style array and at() method access
	std::cout << data[1] << " " << data.at(2) << std::endl;

	// get first element
	std::cout << "First value: " << data.front() << std::endl;

	// get last element
	std::cout << "Last value: " << data.back() << std::endl;

	// assign() method
	data.assign(5);
	for (auto elem : data)
	{
		std::cout << elem << " ";
	}
	std::cout << std::endl;

	// fill() method
	data.fill(6);
	for (auto elem : data)
	{
		std::cout << elem << " ";
	}
	std::cout << std::endl;

    return 0;
}

다른 STL의 컨테이너와 동일하게 반복을 위한 begin(), end() 형태의 메소드가 제공됩니다.

첫 원소나 마지막 원소를 가져오기 위해 front(), back() 메소드를 사용할 수 있습니다.

그리고 크기를 확인할 수 있는 size() 메소드 역시 존재합니다.

배열의 원소의 수를 얻기 위해서 _countof 등을 사용하지 않아도 됩니다.

첫 번째 원소의 주소를 반환하는 data() 메소드가 존재합니다.

기존 배열에서는 배열의 이름이 첫 원소의 주소를 나타냈는데 std::array는 직접 사용이 불가능합니다.

#include <array>
#include <iostream>

int main()
{
	int normal[5] = { 0, 1, 2, 3, 4 };
	int* first = normal;
	std::cout << *first << std::endl;

	// initialization
	std::array<int, 5> data = {0, 1, 2, 3, 4};
	// first = data; // error
	first = data.data();
	std::cout << *first << std::endl;

    return 0;
}

주석 처리된 부분을 해제하면 컴파일 에러가 발생합니다.

또 다른 특징으로는 'Derived-to-base' 형변환을 지원하지 않는다는 점입니다.

#include <array>
#include <iostream>

class Base
{
	virtual void print()
	{
		std::cout << "Base" << std::endl;
	}
};

class Derived : public Base
{
	virtual void print()
	{
		std::cout << "Derived" << std::endl;
	}
};

void foo(std::array<Base, 5> arr)
{
	// do something
}

int main()
{
	std::array<Derived, 5> data;
	foo(data);

    return 0;
}

부모 클래스의 std::array를 받는 함수를 자식 클래스 타입의 std::array로 호출할 수 없습니다.


std::array는 일반적인 배열과 같이 [] 등의 인덱스 기반으로도 사용이 가능합니다.

STL 컨테이너이므로 코드의 일관성을 유지할 수 있습니다.

메소드들을 활용해서 좀 더 안정적으로 코드를 작성할 수도 있습니다.

최근에는 대부분 환경이 C++11을 지원하기 때문에 배열 대신 std::array를 사용하는 것을 추천합니다.



반응형