2017-01-04 1 views
9

std::array의 기본 원시 (C) 배열에 대한 참조를 얻는 정규 방법은 무엇입니까?std :: array에서 원시 배열에 대한 참조 얻기

data() 메서드는 원시 포인터를 반환하기 때문에 부적합합니다. 알려진 크기의 미가공 배열에 대한 참조를 받아들이는 함수로 전달하기위한 것이다.

또한 data()이 원시 포인터를 반환하고 기본 원시 배열에 대한 참조가 아닌 이유가 있습니까? 아니면 그냥 감시입니까?

+5

크기가 큰 배열에 대한 참조를 전달하는 것은 까다 롭고 널리 사용되지 않습니다. 어쨌든 참조가없는 C 코드와 상호 작용하기 위해서만 원시 배열을 사용할 것이기 때문에 왜 그렇게 될까요? – BoBTFish

+3

@WhiZTiM : OP는'std :: array '을'myFunc (int (& k) [5])'로 전달할 수있는 방법이 없음을 의미합니다. (5 int의 배열에 대한 참조). –

+1

위원회는'std :: array'를 우수 대안으로 설계했기 때문일 수 있습니다. 기본 로우 어레이에 대한 참조를 쉽게 얻지 못하게하는 것은 우리가 프로그래밍하기를 원하는 방향으로 조금 움직일 수 있습니다. – StoryTeller

답변

13

std :: array의 기본 raw (C) 배열을 얻는 표준 방법은 무엇입니까?

기본 C 배열을 가져올 방법이 없습니다. 이 단순한 감시는

또한, 데이터()는 원시 포인터를 리턴 충분한 이유가 아닌 기본 원료 어레이에 대한 레퍼런스, 또는인가?

역방향 : std::array에 기본 C 배열을 제공할만한 이유가 없습니다. 앞서 말했듯이 C 배열은 C 배열에 대한 참조를 가져 오는 함수에서만 유용합니다 (원시 포인터를 통해).

때이었다 당신이 함수했던 지난 시간 :

void foo(int (&arr)[5]) 

나를? 못.


template <class T, std::size_t N> 
auto safe_array_size(T (&)[N]) { return N; } 
이의 사용하지 않는 배열에 대한 참조를 매개 변수 이유에 조금 뛰어 보자 : 나는 배열의 크기를 점점 (포인터 거부)를 제외한 C의 배열 참조 매개 변수 기능을 본적이 없어요.

우선, C 영역에서 별도의 크기 매개 변수가있는 포인터가 배열 대 포인터 감쇠 및 참조 유형 부족으로 인해 배열을 전달하는 유일한 방법이었습니다.

C++에는 std::vectorstd::array과 같은 C 배열의 대안이 있습니다. 당신은 C 함수에 전달할 경우 포인터 + 크기 에 붙어 있도록

  • 하면, 참조의 옵션이 없습니다 : 당신이 (레거시) C 배열이 경우에도하지만 당신은이 상황을
  • C++ 함수에 전달하고자 할 때 관용적 인 C++ 방법은 begin + end 포인터를 전달하는 것입니다.

우선 begin + end 반복자는 모든 종류의 컨테이너를 허용합니다. 템플릿을 피하고자 할 때 std::vector에 대한 참조를 보는 것은 드문 일이 아니므로 C 배열을 가지고 있다면 C 배열을 참조하십시오. 큰 결점 때문에 : 배열의 크기를 알아야합니다 :

void foo(int (&arr)[5]) 

매우 제한적입니다.당신은 더 나은 시작 + 대신 최종 템플릿 반복자와 함께 갈 수 있도록, 피 템플릿의 목적을 친다

template <std::size N> 
void foo(int (&arr)[N]) 

:

이 해결하기 위해 당신은 그것을 템플릿을 확인해야합니다.


일부 경우

( 동일한 의미를 가지고 단지 2 또는 3의 값에 예를 들면 수학 계산을하므로 별도의 파라미터이어야한다)을 특정 배열 크기가 요구되며, 제조 기능 일반 은 이해가되지 않습니다. 이 경우 배열의 크기를 지정하면 은 컴파일시 정확한 크기 인 의 배열을 전달할 수 있으므로 안전성이 보장됩니다. 그러므로 유리의와 "큰 단점"적용의 (C 등) C++있는 거대한 범위의 아름다움의

아니다. 그렇습니다. 독특한 방식으로 특정 고유 기능을 사용하거나 필요로하는 필드를 항상 찾을 수 있습니다. 즉, 심지어 당신의 예제에서 나는 배열에서 여전히 부끄러워 할 것입니다. 의미 상으로 분리되어서는 안되는 고정 된 수의 값을 가질 때 구조가 대부분 배열에 대해 올바른 선택이 될 것이라고 생각합니다 (예 : float[4] 대신 glm::mat4).

그러나 std::array이 무엇인지 잊지 마시기 바랍니다 : C 배열의 최신 대체품. 옵션을 분석 할 때 배웠던 한 가지는 절대보다 "더 낫다"는 것입니다. 항상 "의존"이 있습니다. 그러나이 경우가 아닙니다 : std::array은 인터페이스에서 C 배열을 확실하게 대체해야합니다. 따라서 고정 된 크기의 컨테이너가 참조 매개 변수로 필요한 드문 경우에 이미 std::array 일 때 C 배열 사용을 장려하는 것은 의미가 없습니다. 따라서 std::array의 기본 C 배열을 노출하는 유일한 유효한 경우는 C 배열 참조 매개 변수가있는 일부 이전 라이브러리에 대한 것입니다. 그러나 더 큰 그림에서 인터페이스에이를 추가하는 것은 정당화되지 않는다고 생각합니다. 새로운 코드는 struct (btw std::tuple은 각 표준에서 사용하기가 더 쉽고 쉬워졌습니다) 또는 std::array을 사용해야합니다.

+2

어떤 경우에는 (예를 들어, 동일한 의미론을 가진 단지 2 또는 3 값에 대한 수학 계산 때문에 별도의 매개 변수가되어서는 안된다.) 특정 배열 크기가 필요하며 함수를 generic으로 만들지는 않을 것이다. 말이 안돼. 이 경우 배열의 크기를 지정하면 컴파일시에 올바른 크기의 배열 만 전달할 수 있기 때문에 안전성이 보장됩니다. 그러므로 그것은 유리하고 "큰 결점"이 아닙니다. – Danra

+0

@ 단라 좋은 지적. 답안에 귀하의 의견을 통합하십시오. – bolov

+2

나는 C 영역에서도 [특정 크기의 배열로 _pointer_를 가져올 수 있으며, C++에서 특정 크기의 배열에 대한 참조를 취하는 것과 거의 동일한 구문을 사용하는 것이 가능함을 지적하고자합니다.] (http://rextester.com/MHUBK79249); 불행하게도, 다른 크기의 배열에 포인터를 전달하는 것은 내가 알고있는 모든 컴파일러에서 오류가 아닌 경고로 처리됩니다. –

3

하나도 존재하지 않습니다.

특히 레거시 코드로 작업 할 때 왜 유용 할 수 있는지 알 수 있습니다.하지만 수십 년 전에 우리는 이와 같은 코드에서 반복기 인식 알고리즘으로 옮겨 가고 있습니다. 그리고 C 코드로 작업 할 때 어쨌든 포인터를 사용해야합니다. 나는이 기능을 제공하지 않기로 결정한 요인이라고 생각합니다.

가능한 경우 std::array<T, N>&을 수락하도록 코드를 다시 작성하십시오.