Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 배열 타입 조작 함수 완벽 정리: is_array부터 remove_all_extents까지

배열(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

위 결과에서 알 수 있듯이 intstring 같은 단순 타입은 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(): 모든 차원 제거

이러한 함수들은 템플릿 메타프로그래밍이나 제네릭 코드 작성 시 타입을 컴파일 타임에 안전하게 검사하고 변환하는 데 매우 유용하게 활용됩니다.