참조로 배열을 전달할 수 있습니까?
void foo(double& *bar)
내 컴파일러가 아니오라고 말하는 것 같습니다. 왜? 참조로 배열을 전달하는 올바른 방법은 무엇입니까? 아니면 해결 방법? 내 메서드가 수정해야하고 나중에 검색해야하는 배열 인수가 있습니다. 또는이 배열을 잘 작동하는 클래스 멤버로 만들 수 있지만 코드의 다른 부분에는 많은 단점이 있습니다 (피하고 싶습니다).
감사합니다.
참조로 배열을 전달할 수 있습니까?
void foo(double& *bar)
내 컴파일러가 아니오라고 말하는 것 같습니다. 왜? 참조로 배열을 전달하는 올바른 방법은 무엇입니까? 아니면 해결 방법? 내 메서드가 수정해야하고 나중에 검색해야하는 배열 인수가 있습니다. 또는이 배열을 잘 작동하는 클래스 멤버로 만들 수 있지만 코드의 다른 부분에는 많은 단점이 있습니다 (피하고 싶습니다).
감사합니다.
std::vector
보셨습니까?
std::vector
는 크기가 동적 / 알 수없는 경우 분명히 우월하지만 크기가 항상 같은 경우 과잉 일 것이며 대신 std::array
구문 적 추악함을 해결하는 동시에 값 의미를 부여합니다.
답변:
배열은 실제로 참조로만 전달할 수 있습니다.
void foo(double (&bar)[10])
{
}
이렇게하면 다음과 같은 작업을 할 수 없습니다.
double arr[20];
foo(arr); // won't compile
임의의 크기 배열을에 전달할 수 있으려면이를 foo
템플릿으로 만들고 컴파일 타임에 배열의 크기를 캡처합니다.
template<typename T, size_t N>
void foo(T (&bar)[N])
{
// use N here
}
당신은 심각하게 사용하는 것이 좋습니다 std::vector
, 또는 컴파일러가 지원하는 C ++ (11)이있는 경우 std::array
.
foo
되면 배열은 포인터로 붕괴됩니다." 그렇지 않습니다. 10 개 요소의 배열 만 전달할 수 있으므로 크기에 대한 추가 정보가 필요하지 않습니다. (그리고 다시 한 번, 당신은 할 수없는 배열을 전달 void foo( double*& )
암시 적 변환의 결과가를 rvalue이며, const가 아닌 참조를 초기화 할 수 없습니다 당신은 사용해야합니다. void foo( double *const & );
.
void foo(T &bar[N])
내 템플릿에서 하고 있었지만 실제로는 "배열에 대한 참조"가 아니라 "참조의 배열"을 의미합니다.
std::vector
(올바른 크기) 인 경우, 벡터의 내용 (아마를 통해 얻은 std::vector::data()
) 을이 배열 유형으로 캐스트하는 방법은 무엇입니까? 유형 매개 변수의 고정 배열 크기에 대한 구문은 무엇입니까 (예 :와 함께 사용 static_cast<>
)?
reinterpret_cast
동적으로 할당 된 배열 (할당 후 고유 크기가 없음)을 고정 된 크기의 자동 배열로 처리하는 데 허용되지 않음을 알 수 있습니다 . 게다가 그것은 잘못된 질문입니다. 올바른 질문은 '어떻게 내 코드를 두 유형의 컨테이너와 함께 작동하도록 리팩터링 할 수 있습니까?'이고 대답은 템플릿과 반복기 / 범위 또는 크기가 고정되어 있다고 말 했으므로 함수입니다. 데이터 포인터 / 참조 만 취하고 크기를 하드 코딩합니다 (또는 크기가 다를 수있는 경우 데이터 / 크기 어댑터 (예 span
예,하지만 참조에 대한 인수 일치의 경우 포인터에 대한 암시 적 배열이 자동이 아니므로 다음과 같은 것이 필요합니다.
void foo( double (&array)[42] );
또는
void foo( double (&array)[] );
그러나 일치 할 때 double [42]
및 double []
구별되는 유형입니다. 알 수없는 차원의 배열이있는 경우 두 번째와 일치하지만 첫 번째는 일치하지 않으며 42 개 요소가있는 배열이있는 경우 첫 번째와 일치 하지만 두 번째는 일치 하지 않습니다 . (후자는 IMHO, 매우 반 직관적입니다.)
두 번째 경우에도 차원을 전달해야합니다. 함수 내부에 있으면 복구 할 방법이 없기 때문입니다.
double []
와 double [42]
. 두 가지 유형을 당신이 후자의 형태로 전달할 수있는 유일한 것은 알 수없는 길이, 예를 들어 배열 될 것이다 그래서 extern double d[];
, 또는 같은 어떤 심각. 사용성을 제한합니다.)
요소 만 수정하려는 경우 :
void foo(double *bar);
충분합니다.
주소를 (예 :)로 수정하고 realloc
싶지만 배열에서 작동하지 않는 경우 :
void foo(double *&bar);
올바른 형식입니다.
C ++를 사용하고 있으므로 여기에 아직 누락 된 필수 제안은 std::vector<double>
.
참조로 쉽게 전달할 수 있습니다.
void foo(std::vector<double>& bar) {}
C ++ 11을 지원하는 경우 std::array
.
참고로 :
std::vector
일반적으로 최상의 솔루션입니다. 그러나 예외가 있습니다.
다른 대답은 말합니다 마찬가지로 넣어 &
애프터 *
.
이것은 때때로 혼란 스러울 수있는 흥미로운 점을 가져옵니다. 유형은 오른쪽에서 왼쪽으로 읽어야합니다. 예를 들어, 이것은 (맨 오른쪽부터 시작 *
하여) int에 대한 상수 포인터에 대한 포인터입니다.
int * const *x;
따라서 당신이 쓴 것은 참조에 대한 포인터가 될 것입니다.
여기에서 Erik 은 참조로 배열을 전달하는 모든 방법을 설명합니다 . https://stackoverflow.com/a/5724184/5090928 .
마찬가지로 다음 과 같이 배열 참조 변수를 만들 수 있습니다 .
int arr1[] = {1, 2, 3, 4, 5};
int(&arr2)[5] = arr1;