2009-09-08 2 views
10

때때로 문자열의 길이를 상수와 비교해야 할 때가 있습니다. 예를 들어
:컴파일 타임 "strlen()"이 효과적입니까?

if (line.length() > 2) 
{ 
    // Do something... 
} 

하지만 코드에서 "마술"상수를 사용하지 않도록 노력하고 있어요.
보통 나는 그런 코드를 사용 : 그것은 때문에 함수 호출의 더 읽기,하지만 효율적입니다

if (line.length() > strlen("[]")) 
{ 
    // Do something... 
} 

. 꽤 좋은 코드 생성 릴리스 빌드에서

template<size_t N> 
size_t _lenof(const char (&)[N]) 
{ 
    return N - 1; 
} 

template<size_t N> 
size_t _lenof(const wchar_t (&)[N]) 
{ 
    return N - 1; 
} 

// Using: 
if (line.length() > _lenof("[]")) 
{ 
    // Do something... 
} 

(2008 년으로 VisualStudio) :

cmp dword ptr [esp+27Ch],2 
jbe 011D7FA5 

을 그리고 좋은 일이 컴파일러가 포함되지 않는다는 것입니다
나는 다음과 같이 템플릿 함수를 썼다 "[]"바이너리 출력 문자열.

컴파일러 관련 최적화입니까, 아니면 일반적인 동작입니까?

+2

아마 모든 배열 유형에 대해 하나의 템플리트를 사용할 수 있지만, 다음과 같은 것이 있습니다 :'template size_t _lenof (const T (&) [N]) {return N - 1; }', 당신의 예제와 똑같이 작동해야합니다. –

+2

@ Envan Teran : 좋은 생각이지만,이 함수는 '\ 0'을 종료하기 때문에 문자열 (char/wchar_t의 배열)에 대해서만 의미가 있습니다. 함수는 int [10]에서 작동하고 9를 반환합니다. 나는 그것이 의미가 있다고 생각하지 않습니다;) – Dmitriy

+0

@Dmitriy : 실제로 –

답변

4

함수 호출을 인라인 할 수있는 기능은 컴파일러 관련 최적화 모두 공통적 인 동작입니다. 즉, 많은 컴파일러가이를 수행 할 수 있지만 반드시 그렇게 할 필요는 없습니다.

+0

원하는 최적화는 인라이닝을 요구하지 않는다. 컴파일 타임에 문자열의 길이를 계산해야합니다. –

+0

그래도 실제로 최적화는 아닙니다. 길이는 런타임에 계산되지 않고'_lenof' 함수를 호출합니다. 표준에서는 문자열 리터럴에'const char [N]'형식을 제공해야합니까? 그리고 컴파일러가 템플릿 함수의 인수를 'N'으로 추론하는 데 필요한 이러한 유형의 값이 아닌가? –

+0

죄송합니다. 귀하의 답변이 무엇을 가리키고 있는지 오해했습니다. 어떤 이유에서든 "[strlen] 함수 호출로 인해 효율적이지 않습니다."에 대해 이야기하고 있었지만 말입니다. 컴파일러가 _lenof를 인라인 할 수 없다면, 아마도 인라인 할 수 없으며 일반적으로 C++ 컴파일러가 될 것입니다. 템플렛의 심각한 사용은 악몽 일 것입니다 ... –

12

 
sizeof "[]" - 1; 

(마이너스 후행 널 (null)에 대한 하나의 당신은 를 sizeof 할 수있는 "[]."- '\ 0'를 sizeof하지만, '\ 0' 종종는 sizeof이다는 sizeof (int)를 C에서, 그리고 "- 1"완벽하게 읽을 수 입니다)

+0

은 넓은 문자열 (예 : L "[]")에서는 작동하지 않습니다. – Dmitriy

+1

은 넓은 문자열로 고정 될 수 있습니다. '(sizeof (L "[]")/sizeof (L "")) - 1' –

+0

@ Envan Teran : 예. 그러나 매크로를 사용하여 읽기 쉽도록해야합니다. IMHO 매크로는 더 C 스타일이지만 C++이 아닙니다. – Dmitriy

-7
#define TWO 2 
#define STRING_LENGTH 2 
/* ... etc ... */ 

심각, 왜 단지 2를 입력 방지하기 위해 모든 번거 로움을 통해 이동합니다.? 나는 솔직히 당신이 당신의 코드를 덜 읽을 수있게 만들고 있다고 생각하고, 다른 프로그래머들은 당신이 쓴 커피를 필터에서 뽑아내는 것처럼 쳐다볼 것입니다.

+0

예입니다. 실제 코드에서는 "약간의 문자열"처럼 보입니다. 이 경우 문자 수를 세지 않습니까? :) – Dmitriy

+0

예, 있습니다. 그럴거야. 그리고 나는 그렇다. –

+2

@Jed Smith : :) 문자열이 바뀌면 매크로 정의를 변경하는 것을 잊지 않았습니까? – Dmitriy

2

최적화가 활성화되면 대부분의 컴파일러가 을 최적화 할 것이라고 생각합니다.. 장애인이라면 프로그램이 필요한 것보다 훨씬 느려질 수 있습니다.

런타임시 strlen을 호출하지 않기 때문에 템플릿 함수를 선호합니다. 물론, 오히려 charwchar_t에 대해 별도의 함수를 작성하는 대신 다른 템플릿 인수를 추가하고, 모든 유형의 작동 기능을 얻을 수 있습니다 : (이미 댓글에서 언급 한 바와 같이,이 재미있는 결과를 얻을 수

template <typename Char_t, int len> 
int static_strlen(const Char_t (&)[N] array){ 
    return len/sizeof(Char_t) - 1; 
} 

을)

마지막 메모를 int 배열을 통과,하지만 당신은 그렇게 할 것입니까? 그것은 문자열을 의미하는 것, 결국 경우, 이름 _strlen나쁜입니다. 밑줄로 시작하는 네임 스페이스 범위의 모든 이름은 구현에 예약되어 있습니다. 불쾌한 명명 충돌이 발생할 위험이 있습니다.

그런데 왜 [2]보다 마법 상수가 적습니까?

두 경우 모두 비교할 문자열 형식이 변경되면 리터럴이어야합니다.

+0

어떤 이유로 든 함수는 strlen을 사용하는 것보다 빠르지 않습니다. 그러나 그것은 std :: char_traits :: length를 사용하는 것보다 빠르다고 보여 지므로 strlen은 char 배열에서만 작동하므로 여전히 유용합니다. – leetNightshade

관련 문제