std::array
C++ 11에 추가된 std::array는 <array>에 정의되어 있다. C 스타일의 배열과 다른 점은 배열의 이름이 `T*`로 자동 형변환 되지 않는다. C 스타일의 배열을 사용하게 되면 함수 매개변수에 집어넣었을 때, 포인터로 강제 변환되어 배열의 크기가 날라가는 불편한 점도 초래한다. 배열 크기가 소멸되는 이유는 `int arr[]`처럼 함수의 매개변수를 설정하더라도, 함수 내부에서 `int* arr`와 동일하게 해석한다. (sizeof() 연산하면, 그냥 포인터 크기만 계산됨.) 이 떄문에 배열의 크기를 같이 함수 매개변수에 넘겨주어야 하는 과정이 생긴다.
또한 반복자(iterator), 대입 연산자 등을 사용할 수 있다. 이 덕분에 <algorithm>에 정의된 함수를 std::array에 사용할 수 있는데, 예를 들어 sort와 같은 함수도 다음과 같은 형태로 사용할 수 있다.
std::array<int, 5> a;
std::sort(a.begin(), a.end());
생성자
std::array는 aggregate 타입으로, aggregate initilization이 가능하다. (struct 변수를 초기화 할 때 중괄호를 통해 초기화를 하는 것처럼.)
#include <array>
std::array<int, 5> a = {1, 2, 3, 4, 5};
대입 연산자
std::array를 사용할 경우 배열간 대입 연산이 가능해진다.
std::array<int, 5> a1 = {1, 2, 3, 4, 5};
std::array<int, 5> a2;
a2 = a1;
for (auto val : a2) {
std::cout << "val: " << val << '\n';
}
/*
val: 1
val: 2
val: 3
val: 4
val: 5
*/
하지만 C 스타일의 배열 같은 경우는 "Array type int[3] is not assignable"과 같은 에러를 보여준다.
int arr[3] = {1, 2, 3};
int b[3];
b = arr; // 에러 발생
원하는 연산을 수행하려면 memcpy 함수를 통해 복사를 해주어야 한다.
멤버 접근 함수
at, operator[]
위 두 함수 모두 인자로 전달한 위치에 있는 원소의 레퍼런스를 반환한다. `at()`의 경우 인덱스의 위치를 체크해서 인덱스가 배열의 범위를 벗어나면 예외를 throw한다.
정상 작동
std::array<int, 3> arr = {1, 2, 3};
std::cout << arr.at(1);
// 출력: 2
예외 처리
std::array<int, 3> arr = {1, 2, 3};
std::cout << arr.at(3);
/* 출력
terminate called after throwing an instance of 'std::out_of_range'
what(): array::at: __n (which is 3) >= _Nm (which is 3)
*/
std::out_of_range 익셉션을 반환하는 것을 확인 가능하다.
opertor[]는 .at()과 달리 C스타일 배열처 범위를 따로 체크하지 않는다.
std::array<int, 3> arr = {1, 2, 3};
std::cout << arr[2];
// 출력: 3
std::array<int, 3> arr = {1, 2, 3};
std::cout << arr[3];
// 출력: -977053312
함수에 대한 값의 복사와 전달
std::array는 매개변수로 전달될 때 값 복사가 된다. return을 할 때도 포인터가 아닌 값을 그대로 반환할 수 있다.
만약, 참조로 전달하고 싶다면 다음과 같이 매개변수를 선언한다.
void foo(std::array<int, 5>& arr);
그리고 여기서 값의 수정이 발생하지 않도록 한다면,
void foo(const std::array<int, 5>& arr);
이와 같이 선언하면 된다.
C 스타일과 비교한 std::array의 장점 요약
- STL 스타일의 반복자 기반 알고리즘과 함께 사용가능 하다.
- C 스타일의 배열과 다르게 함수 매개변수에 값으로 전달하거나, 반환할 수 있다.
- at()을 사용하여 예외처리가 가능하다.
- C 스타일의 배열과 성능은 완전 동일하다.
C 코드의 확장성을 염두에 둔 것이 아니라면, 얌전히 std::array를 사용해야 겠다.
참고 자료
- https://modoocode.com/314
- https://velog.io/@hwhyeons/C-stdarray-vs-C-Style-Array
- https://stackoverflow.com/questions/30263303/what-are-the-advantages-of-using-stdarray-over-c-style-arrays
'C,C++' 카테고리의 다른 글
| [C++] int8_t, int_least8_t and int_fast8_t 차이 (0) | 2025.10.05 |
|---|---|
| [C++] 데이터 타입의 크기 지정 방식과 ABI (0) | 2025.09.24 |
| [C++] Data Types, Type Modifier (0) | 2025.05.03 |
| [C++] 부동소수점의 암시적 변환(Implicit conversions)과 Usual arithmetic conversions (0) | 2025.02.24 |
| [C++] Bitwise not 연산 (0) | 2025.02.11 |