2011-08-11 4 views
1

누군가 다음과 같은 행동을 설명 할 수 있기를 희망합니다.sizeof 및 참조 전달

배열의 길이를 결정하지만 매크로를 사용하지 않으려는 함수를 구현하려고한다고 가정합니다. 예를 들어

#define array_length(x) (sizeof(x)/sizeof(x[0])) 

매개 변수 유형으로 작동해야한다는 점을 감안할 때 템플릿을 사용해야합니다.

첫 시도는 다음과 같이 보입니다.

template <typename T> 
inline size_t 
array_length(const T argument) { 
    return sizeof(argument)/sizeof(argument[0]); 
} 

인수가 포인터로 처리되기 때문에 작동하지 않습니다. T가 T &으로 변경되면 모든 것이 멋지게 작동합니다.

누구든지 언어 구현 수준에서 어떤 일이 일어나고 있는지 말할 수 있는지 궁금합니다. 예를 들어 참조가 함수 인수로 사용될 때 함수에 전달되는 추가 정보는 무엇입니까?

답변

5

이의 두 기능 템플릿을 생각해 보자

int a[10]; 

우리가 f(a); 무엇 전화됩니까? 명시 적으로 템플릿에 인수를 제공하지 않기 때문에 인수 공제가 시작되고 컴파일러는 인수를 기반으로하는 T을 파악하려고합니다. 인수의 형식은 int[10]입니다. T은 절대 참조 유형으로 추론되지 않으며 배열을 값으로 전달할 수 없으므로 배열 간 암시 적 변환이 수행되고 Tint*으로 추론됩니다.

g(a);으로 전화하면 어떻게됩니까? 다시 말하지만, 인수 공제를 사용하여 T이 무엇인지 판단합니다. 매개 변수의 형식은 이고 T을 참조하므로 T은 직접 int[10] 인 것으로 추론 할 수 있으며 배열에서 포인터로의 변환은 수행되지 않습니다.

template <typename T, std::size_t N> 
std::size_t array_length(T const (&)[N]) { return N; } 
2

AFAIK 매크로 외부에서이를 수행하는 좋은 방법은 없습니다. 그래서 나는 std::array (C++ 0x의 새 클래스, "old"C++에 대해서도 사용 가능한 boost::array에서 진화) 또는 std::vector을 사용하는 것입니다.

template <typename T> void f(T); 
template <typename T> void g(T const&); 

를 그리고 이제 우리는 배열이 있다고 가정 해 봅시다 :

+0

+1은'std :: array'에 대해서 +1이지만, 매크로를 요구하는 것에 대해서는 : OP 자신의 시도는 다른 대답에 의해 보여지는 템플릿보다 열등합니다. – UncleBens

1

나는 당신이 더 많은 기술 정보를 찾고 알아,하지만 당신이 얻을 수있는 배열의 길이를 찾는 가장 좋은 방법은 명시 적으로 템플릿 배열을 얻을 것을 요구하는 것입니다

주 템플릿 인수 공제를 사용하여 매크로없이 배열의 요소 번호 :

template<typename T, size_t N> 
size_t ElementCount(const T (&x)[N]) 
{ 
    return N; 
} 

이처럼 사용

int x[15]; 
size_t elements = ElementCount(x);