2013-01-21 4 views
5

C++ 11에서 사용할 수있는 "각 스타일"의 구문은 배열의 실제 크기 (요소 수)를 모른 채 배열 반복을 허용하는 것처럼 보일 것입니다. 새로운 표준의 일부이기 때문에 C 배열의 경우에도 이것이 완벽하게 안전하다고 가정합니다. 일반적으로, 당신은 또한 별도로 조작하기 전에 C 배열의 크기를 알고 있어야하지만, 누군가가 당신이 예상대로 정확히 작동이 새로운 C++ 기술과 경험에서 내가 검증을 원하는 :C++의 범위 기반 루프

extern float bunch[100]; 

for (float &f : bunch) { 
    f += someNumber; 
} 

아무것도 나는 거기 이 기술에 대한 명백하지 않은 부작용 또는 단점을 알아야합니까? 아마도 코드의 상당 부분이 표준에 나오기 전에 작성된 코드 일 것입니다. 희소 한 사용법이 잘 알려지지 않은 다른 이유 때문이 아닌지 확인하고 싶습니다.

+10

배열의 크기를 항상 알 수 있습니다 (https://gist.github.com/3959946#file-arrays-h-L33). 이것을 포인터로 변환하면 크기를 알지 못하게됩니다. –

+1

@ R.MartinhoFernandes : 좋은 요지! –

+2

일반적으로 평범한 배열을 사용하고 표준 라이브러리 컨테이너로 이동하면 더 행복한 C++ 생활을 누릴 수있다. –

답변

4

그 용도에 대해 이상하거나 위험하지 않습니다. 배열의 크기는 컴파일 타임에 알려 지므로 루프에서 사용할 수 있습니다.

template< class T, std::size_t N > 
std::size_t length(const T (&)[N]) 
{ 
    return N; 
} 

Foo f[5]; 
std::cout << length(f) << "\n"; 

이 분명히 동적 크기의 C-스타일이 기술, 또는 범위를 기반으로 루프를 사용할 수 있는지 확인해야한다 : 이것은 당신이 배열의 길이를 알 수있는 템플릿 함수의 예입니다 배열. 물론

, 당신이 다음 범위를 기반으로 루프가 있다면 당신은 또한 당신은 완전히 C 스타일 배열을 피할 수 있도록, (그렇지 않으면, 당신은 아마 std::tr1 또는 부스트에서 TI를 얻을 수 있습니다) std::array이 있어야합니다

extern std::array<float, 100> bunch; 

for (auto &f : bunch) { 
    f += someNumber; 
} 
+0

아, 아마도 혼란은 C 배열과'std :: array'의 차이입니다. 범위 기반은 후자에는 유효하지만 이전에는 유효하지 않습니까? 항상 C 배열은 자체 크기 (길이) – johnbakers

+1

@SebbyJohanns no에 대한 지식을 제공하지 않는다는 것을 항상 생각하고 읽었 기 때문에 C 스타일 배열이 정적으로 정해진 경우 두 가지 모두에 유효합니다. 위의 템플릿 함수는 그러한 배열로부터 크기를 다시 얻을 수 있음을 보여줍니다. – juanchopanza

+0

즉, 스택의 배열에서 작동하지만 힙에서는 작동하지 않습니다. – johnbakers

2

배열을 참조로 전달하고 형식과 길이를 추론 할 수 있습니다.

#include <iostream> 

template<typename T, size_t N> 
void fun(T const (&arr)[N]) 
{ 
    for (std::size_t i = 0; i < N; ++i) 
     std::cout << arr[i] << " "; 
} 

int main() 
{ 
    int x[] = { 1, 2, 3 }; // no need to set length here 
    fun(x); // 1 2 3, no need to specify type and length here 
} 
+1

이 템플릿을 보면'N '을위한'size_t'가'fun' 함수에 어떻게 전달되는지에 대해 명확하지 않다. 'N '에 대한 값을 어떻게 추출합니까? – johnbakers

+0

템플릿 인수 공제 중 컴파일러는 인수 (int [3] 유형의 x)와 형식 매개 변수 (T [N] 유형의 arr)를 확인하고 T에 int를 대입하고 N에 3을 사용하면 정확한 시합. – TemplateRex

+0

@SebbyJohanns 고정 크기 배열의 유형에는 크기가 들어 있습니다. 템플릿 매개 변수 차감을 사용하면됩니다. – juanchopanza

4

범위 기반 for 루프를 배열과 함께 사용하는 것이 안전합니다. 포인터에서 실수로 실수로 사용할 수 있다고 생각됩니다.

float* array = new float[100]; 
for (float& f : array) { 
    // ... 
} 

걱정하지 마십시오. 이 경우 컴파일러에서 오류가 발생합니다. 그래서 안전하지 않은 경우, 어쨌든 컴파일 오류가 발생합니다.

+0

어쨌든'new []'를 사용하는 것은 그 자신의 벙어리 오류 일 것입니다. – Puppy

+0

@DeadMG'new float [100]'의 문제점은 무엇입니까? – johnbakers

+1

@DeadMG : "벙어리"는 "알지 못함"과 다릅니다. –