2012-05-04 2 views
0

나는이 질문을 여러 번 물었고 컴파일 타임에 그렇게했기 때문에 어떻게해야하는지 묻지 않았다. 내 질문은 내가 어떻게 이해가 안되기 때문에 그것이 어떻게 작동하는지입니다. 함수에 char[]를 전달할 때C++에서 컴파일 타임에 정적 문자 배열 크기

는 그것의 정보를 푼다 및 char*을지고 그 때문에 우리는 템플릿을 사용하여 컴파일시에 문자 배열의 크기를 얻을 수 없다, 그래서 난 시도 자체를 문자열을 전달하고 일 :

template <int N> inline int arr_len(const char (&)[N]) { return N - 1; } 

#define STR "this is an example!" 

const char *str_ptr = STR; 

int main() 
{ 
    int array_size = arr_len(STR); 
} 

이 코드는 VC++ 2008, Intel C++ 12 및 GCC 4.7에서 테스트되었으며 작동합니다.

문자열 자체를 전달하면 컴파일러에서 const char[]으로 간주합니다. 적어도 내가 생각한 것입니다. 그리고 문자열 크기를 얻을 수 있습니까? 어떻게 가능합니까?

+0

사용하는 배열의 크기가 서로 다른 경우 'arr_len'버전이 다르며 작업 할 수있는 유일한 유형의 배열의 길이를 반환합니다. –

+0

맞지만 최적화가되면 문자열 길이가됩니다. –

+0

사실 그것은 최적화와 관련이 없습니다. 이 모든 것은 컴파일 할 때 발생합니다. –

답변

3

문자열 리터럴 타입 배열이 아닌 포인터이다. 따라서, 참조에 의해 배열을 취하는 함수에 직접 전달하면 포인터로 쇠퇴하지 않습니다.

1

왜냐하면 STR은 컴파일러가 시작되기 전에 대체되는 매크로이기 때문입니다.

"XXXX"는 문자열 리터럴 (배열이 아님)으로 바꿉니다.

것은이 작업을 얻기 위해 수행

char const str_ptr[] = "XXX YYY"; 
       // ^^^^ Compiler works out size 

int main() 
{ 
    int array_size = arr_len(str_ptr); 
         // ^^^^^^^ pass in an object that has a type. 
}; 
0

함수의 매개 변수 유형을 임시로 배열로 식별하면 매개 변수 유형이 배열의 요소 유형에 대한 포인터가되도록 '조정'됩니다.

그래서 쓸 때 : void foo(char c[]) 컴파일러는 효과적으로 void foo(char *c)이되도록 다시 씁니다. 당신이 배열을 통과 할 때 다음 :

char x[10]; 
foo(x); 

C++은 void foo(char *c)을 발견하고 그것이 char *char [] 인수를 변환 함수를 호출하고,이 그것을 수행 정확히 무엇을 할 수 있음을 본다.

그러나 함수 유형의 조정은 작성된 매개 변수 유형이 배열 인 경우에만 발생합니다. 배열에 대한 참조는 배열이 아니므로 함수 void bar(char (&c)[10])을 선언 할 때 동등한 조정이 수행되지 않습니다.

질문에 대답하는 데 필요한 두 번째 비트는 문자열 리터럴 형식이 const char 배열입니다. const char (&)[N] 함수를 사용하여 함수 호출에서 문자열 리터럴을 직접 작성하면 C++은 "array -> first element to pointer"변환 대신에 배열에 대한 참조를 전달할 수 있음을 알게됩니다. 그래서 그것이하는 일이고 템플릿 유형 공제는 문자열의 크기에 맞는 숫자를 찾습니다.

관련 문제