배열(Array)은 동일한 데이터 타입의 여러 데이터 요소를 연속된 메모리 공간에 저장하는 C++의 기본 자료 구조입니다.
C++에서는 배열 타입을 다룰 수 있도록 다양한 내장 함수를 제공하며, 일부 함수는 다차원 배열에도 적용할 수 있습니다. 이러한 함수들은 <type_traits> 헤더 파일에 포함되어 있어, 별도의 라이브러리 설치 없이 바로 사용할 수 있습니다.
이 글에서는 C++에서 배열 타입을 조작하는 대표적인 함수들을 예제 코드와 함께 하나씩 살펴보겠습니다.
1. is_array() – 배열 여부 확인
is_array() 함수는 함수에 전달된 변수가 배열 타입인지 아닌지를 검사합니다. 이 함수는 매우 엄격하게 판별하기 때문에 std::array조차 배열로 인정하지 않습니다. 반환값은 불리언 형태로, 배열이 전달되면 true(1), 그렇지 않으면 false(0)을 반환합니다.
예제
#include<type_traits>
#include<iostream>
#include<array>
#include<string>
using namespace std;
int main(){
cout<<"Checking if int is an array ? : ";
is_array<int>::value?cout<<"True":cout<<"False";
cout<<"\nChecking if int[] is an array? : ";
is_array<int[6]>::value?cout<<"True":cout<<"False";
cout<<"\nChecking if 2D Array is an array? : ";
is_array<int[2][3]>::value?cout<<"True":cout<<"False";
cout<<"\nChecking if String is an array? : ";
is_array<string>::value?cout<<"True":cout<<"False";
cout<<"\nChecking if Character Array is an array? : ";
is_array<char[4]>::value?cout<<"True":cout<<"False";
cout << endl;
return 0;
}실행 결과
Checking if int is an array ? : False Checking if int[] is an array? : True Checking if 2D Array is an array? : True Checking if String is an array? : False Checking if Character Array is an array? : True
위 결과에서 알 수 있듯이 int나 string 같은 단순 타입은 false를 반환하고, 1차원·2차원 배열 및 문자 배열만 true를 반환합니다.
2. is_same() – 두 타입의 동일성 비교
is_same() 함수는 전달된 두 타입이 완전히 동일한지, 즉 두 타입의 설계도(blueprint)가 정확히 같은지를 검사합니다. 배열의 경우 크기와 차원까지 모두 일치해야 true를 반환합니다.
예제
#include<type_traits>
#include<iostream>
#include<array>
#include<string>
using namespace std;
int main(){
cout << "Checking if 1D array is same as 1D array (Different sizes) ? : " ;
is_same<int[3],int[4]>::value?cout<<"True":cout<<"False";
cout << "\nChecking if 1D array is same as 1D array? (Same sizes): " ;
is_same<int[5],int[5]>::value?cout<<"True":cout<<"False";
cout << "\nChecking If 2D array is same as 1D array? : ";
is_same<int[3],int[3][4]>::value?cout<<"True":cout<<"False";
cout << "\nChecking if Character array is same as Integer array? : " ;
is_same<int[5],char[5]>::value?cout<<"True":cout<<"False";
return 0;
}실행 결과
Checking if 1D array is same as 1D array (Different sizes) ? : False Checking if 1D array is same as 1D array? (Same sizes): True Checking If 2D array is same as 1D array? : False Checking if Character array is same as Integer array? : False
크기가 다른 1차원 배열끼리, 차원이 다른 배열끼리, 요소 타입이 다른 배열끼리는 모두 false로 판정됩니다. 오직 크기와 타입이 모두 같은 경우에만 true가 나옵니다.
3. rank() – 배열의 차원(랭크) 확인
rank() 함수는 전달된 배열의 랭크(rank), 즉 배열의 차원 수를 정수 값으로 반환합니다. 일반 변수는 0, 1차원 배열은 1, 2차원 배열은 2를 반환하는 식입니다.
예제
#include<type_traits>
#include<iostream>
using namespace std;
int main(){
cout<<"Print rank for the following types of arrays : \n";
cout<<"integer : "<<rank<int>::value<<endl;
cout<<"1D integer array (int[]) : "<< rank<int[5]>::value<<endl;
cout<<"2D integer array (int[][]) : "<<rank<int[2][2]>::value<<endl;
cout<<"3D integer array (int[][][]) : "<<rank<int[2][3][4]>::value<<endl;
cout<<"1D character array : "<<rank<char[10]>::value<<endl;
}실행 결과
Print rank for the following types of arrays : integer : 0 1D integer array (int[]) : 1 2D integer array (int[][]) : 2 3D integer array (int[][][]) : 3 1D character array : 1
4. extent() – 특정 차원의 크기 확인
extent() 메서드는 배열의 특정 차원 크기를 반환합니다. 이 함수는 배열 타입과 차원 인덱스라는 두 개의 입력 매개변수를 받으며, 존재하지 않는 차원을 조회하면 0을 반환합니다.
예제
#include<type_traits>
#include<iostream>
using namespace std;
int main(){
cout<<"Printing the length of all dimensions of the array arr[2][45][5] :\n";
cout<<"1st dimension : "<<extent<int[2][45][5],0>::value<<endl;
cout<<"2nd dimension : "<<extent<int[2][45][5],1>::value<<endl;
cout<<"3rd dimension : "<<extent<int[2][45][5],2>::value<<endl;
cout<<"4th dimension : "<<extent<int[2][45][5],3>::value<<endl;
}실행 결과
Printing the length of all dimensions of the array arr[2][45][5] : 1st dimension : 2 2nd dimension : 45 3rd dimension : 5 4th dimension : 0
배열 arr[2][45][5]는 3차원 배열이므로, 존재하지 않는 4번째 차원을 조회했을 때 0이 출력됩니다.
5. remove_extent() – 첫 번째 차원 제거
remove_extent() 함수는 다차원 배열에서 첫 번째 차원을 제거합니다. 예를 들어 3차원 배열에 적용하면 2차원 배열 타입으로 변환됩니다.
예제
#include<type_traits>
#include<iostream>
using namespace std;
int main(){
cout<<"Removing extent of the array arr[2][5][4] : \n";
cout<<"Initial rank : "<<rank<int[2][5][4]>::value<<endl;
cout<<"The rank after removing 1 extent is : " ;
cout << rank<remove_extent<int[20][10][30]>::type>::value << endl;
cout << "length of 1st dimension after removal is :";
cout<<extent<remove_extent<int[20][10][30]>::type>::value << endl;
}실행 결과
Removing extent of the array arr[2][5][4] : Initial rank : 3 The rank after removing 1 extent is : 2 length of 1st dimension after removal is :10
3차원 배열 int[20][10][30]에서 첫 번째 차원이 제거되어 랭크가 3에서 2로 줄었고, 새로운 첫 번째 차원의 크기는 10이 된 것을 확인할 수 있습니다.
6. remove_all_extents() – 모든 차원 한 번에 제거
remove_all_extents() 함수는 배열의 모든 차원을 한 번에 제거합니다. 그 결과 배열은 배열과 동일한 타입의 일반 변수 타입으로 변환되며, 랭크는 0이 됩니다.
예제
#include<type_traits>
#include<iostream>
using namespace std;
int main(){
cout<<"Removing all extents of the array arr[2][5][4] : \n";
cout<<"Initial rank : "<<rank<int[2][5][4]>::value<<endl;
cout<<"The rank after removing all extents is : " ;
cout << rank<remove_all_extents<int[20][10][30]>::type>::value << endl;
cout << "length of 1st dimension after removal is :";
cout<<extent<remove_all_extents<int[20][10][30]>::type>::value << endl;
}실행 결과
Removing all extents of the array arr[2][5][4] : Initial rank : 3 The rank after removing all extents is : 0 length of 1st dimension after removal is :0
모든 차원이 제거되어 랭크가 0이 되었고, 더 이상 차원이 존재하지 않으므로 extent() 조회 결과도 0으로 출력됩니다.
마무리
지금까지 C++의 <type_traits> 헤더에서 제공하는 배열 타입 조작 함수들을 살펴보았습니다. 각 함수의 역할을 정리하면 다음과 같습니다.
- is_array(): 해당 타입이 배열인지 검사
- is_same(): 두 타입이 완전히 동일한지 비교
- rank(): 배열의 차원 수(랭크) 반환
- extent(): 특정 차원의 크기 반환
- remove_extent(): 첫 번째 차원 제거
- remove_all_extents(): 모든 차원 제거
이러한 함수들은 템플릿 메타프로그래밍이나 제네릭 코드 작성 시 타입을 컴파일 타임에 안전하게 검사하고 변환하는 데 매우 유용하게 활용됩니다.