2010-07-30 2 views
40

가능한 중복 :이 코드가 어떻게 작동하는지
Can someone explain this template code that gives me the size of an array?
Magic arguments in function templates…이 "크기의 배열"템플릿 기능은 어떻게 작동합니까?

누군가가 설명 할 수 있습니까? 이 코드의 목적이 배열의 길이를 얻을 것을 알고 있지만,이 코드가 어떻게 작동하는지 모르겠어요 :

template<typename T, int size> 
int GetArrLength(T(&)[size]){return size;} 

감사합니다.

+0

크기가 없습니다 ... –

+5

@thyrgle : 이것은 'sizeof'보다 이점이 있습니다. , 실수로 배열 대신 포인터를 주면 컴파일되지 않습니다. –

+1

또 다른 중복. 그래서 정말 모든 속임수에 문제가 있습니다. http://stackoverflow.com/questions/437150/can-someone- 이 템플릿 코드를 설명해주세요. (이것에 대해 다른 여러 가지 속임수가 있습니다.) 나는 이것이 내가 찾아서 표시하는 유일한 사람인지 궁금합니다. 4 개의 표를 필요로하는이 속임수는 거의 닫히지 않습니다. 다른 질문 에서처럼 그렇게 표시했습니다. 명성이 높은 사람들의 투표는 다른 사람들의 투표 수보다 많아야합니다. 이렇게하면 질문을 더 빨리 닫을 수 있습니다 .. –

답변

50

먼저 매개 변수 T(&)[size]을 분석합시다. 내부에서 오른쪽에서 왼쪽으로 괄호 그룹을 먼저 읽습니다. 이것은 T 유형의 size 크기 배열에 대한 참조 인 이름없는 매개 변수입니다.

즉, 배열의 유형 및 크기가 템플리트 매개 변수 인 모든 배열에 대한 참조를 허용합니다.

우리가 등을 호출하는 경우 :

int a[10]; 
GetArrLength(a); 

컴파일러는 템플릿 매개 변수를 추론하려고합니다. 전달하려는 매개 변수 유형이 T 인 경우 int이어야하며 size은 10이어야합니다 (매개 변수를 배열에 대한 참조를 1int 초로 지정해야 함).

그런 다음 배열의 요소 수를 알려주는 크기를 반환합니다.


이 코드에는 두 가지 "문제"가 있습니다. 첫째, 크기는 음수 일 수 없으므로 서명 된 유형을 템플릿 매개 변수 및 반환 유형으로 사용하는 것은 이치에 맞지 않습니다. 대신 부호없는 유형을 사용해야합니다. 최선 std::size_t 것이다 :

template<typename T, std::size_t Size> 
std::size_t GetArrLength(T(&)[Size]) { return size; } 

번째는이 함수의 결과는 배열의 크기는, 비록 일정한 표현하지 않다는 것이다. 대부분의 상황에서 괜찮 으면 좋겠지 만, 상수 표현을 얻을 수 있다면 더 좋을 것입니다.

template <std::size_t N> 
struct type_of_size 
{ 
    typedef char type[N]; 
}; 

template <typename T, std::size_t Size> 
typename type_of_size<Size>::type& sizeof_array_helper(T(&)[Size]); 

#define sizeof_array(pArray) sizeof(sizeof_array_helper(pArray)) 

이 같은 사용됩니다 :

그것은 세 가지 방식으로 작동
int a[10]; 
const std::size_t n = sizeof_array(a); // constant-expression! 

가 : 첫 번째는 위와 같은 생각이다, 그 템플릿 매개 변수가 채워집니다 즉,이 솔루션으로 끝날 어디 배열의 크기를 알려줍니다.

두 번째 부분은 해당 정보를 사용하여 특정 크기의 유형을 만들기 때문에 type_of_size 도우미입니다. 그 부분은 꼭 필요한 것은 아니지만 코드를 읽기 쉽게 만든다고 생각합니다. A char[N]N과 같은 크기입니다. 따라서 우리는 배열의 크기를 "저장"하기 위해 남용 할 수 있습니다 ... 유형 크기로!

세 번째 부분은 sizeof으로 그 크기를 얻고 있습니다. 실제로 아무 것도 평가하지 않기 때문에 함수에 대한 정의가 필요하지 않습니다. 그것은 단순히 "당신이 이것을한다면 ...크기는 ... "이됩니다. 그리고 크기는 char 배열의"저장 "크기입니다.

+0

하지만 코드를 T & [크기] 으로 변경하면 작동하지 않습니다. 이유가 무엇입니까? (&)과 (와)의 차이점은 무엇입니까? 감사합니다. – BobAlmond

+5

T & [크기]는 참조 배열입니다. 당신은 배열에 대한 참조를 원한다. –

+0

@Bob : 선언과 관련이 있습니다. 이름이 없기 때문에 혼란 스러울 수 있습니다. 거기에 스티커를 붙여보십시오. 'T (& x) [N]'x는 N T의 배열에 대한 참조입니다. 그러나 with :'T & x [N]'x는 T에 대한 N 개의 참조 배열입니다. (불법입니다.) 안쪽에서 오른쪽에서 왼쪽으로 괄호를 먼저 읽습니다. – GManNickG