[c++] 반복하지 않고 배열의 내용을 C ++의 std :: vector에 어떻게 복사합니까?

나중에 처리하기 위해 저장해야하는 프로그램의 다른 부분에서 내 함수로 전달되는 값 배열이 있습니다. 데이터를 처리 할 시간이되기 전에 내 함수가 몇 번 호출 될지 모르기 때문에 동적 저장 구조가 필요하므로 std::vector. push_back모든 값에 대해 개별적으로 표준 루프를 수행 할 필요가 없습니다 memcpy..



답변

배열과 배열 크기를 얻은 후에 벡터를 구성 할 수 있다면 다음과 같이 말할 수 있습니다.

std::vector<ValueType> vec(a, a + n);

a배열이고 n포함 된 요소의 수 라고 가정 합니다 . 그렇지 않으면 std::copy()w / resize()가 트릭을 수행합니다.

memcpy()값이 POD (plain-old data) 유형이라는 것을 확신 할 수없는 한 멀리 떨어져 있습니다.

또한 이들 중 어느 것도 for 루프를 피할 수 없다는 점은 주목할 가치가 있습니다. 코드에서 확인해야하는지 여부에 대한 질문 일뿐입니다. O (n) 런타임 성능은 값 복사를 위해 불가피합니다.

마지막으로 C 스타일 배열은 대부분의 STL 알고리즘에 대해 완벽하게 유효한 컨테이너입니다. 원시 포인터는 begin(), ( ptr + n)는 end().


답변

여기에 많은 답변이 있었고 거의 모두가 작업을 완료 할 것입니다.

그러나 잘못된 조언이 있습니다!

옵션은 다음과 같습니다.

vector<int> dataVec;

int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
unsigned dataArraySize = sizeof(dataArray) / sizeof(int);

// Method 1: Copy the array to the vector using back_inserter.
{
    copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec));
}

// Method 2: Same as 1 but pre-extend the vector by the size of the array using reserve
{
    dataVec.reserve(dataVec.size() + dataArraySize);
    copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec));
}

// Method 3: Memcpy
{
    dataVec.resize(dataVec.size() + dataArraySize);
    memcpy(&dataVec[dataVec.size() - dataArraySize], &dataArray[0], dataArraySize * sizeof(int));
}

// Method 4: vector::insert
{
    dataVec.insert(dataVec.end(), &dataArray[0], &dataArray[dataArraySize]);
}

// Method 5: vector + vector
{
    vector<int> dataVec2(&dataArray[0], &dataArray[dataArraySize]);
    dataVec.insert(dataVec.end(), dataVec2.begin(), dataVec2.end());
}

긴 이야기를 짧게 잘라내려면 vector :: insert를 사용하는 방법 4는 bsruth의 시나리오에 가장 적합합니다.

다음은 몇 가지 세부 사항입니다.

방법 1 은 아마도 가장 이해하기 쉬운 것입니다. 배열에서 각 요소를 복사하여 벡터 뒤쪽으로 밀어 넣으면됩니다. 아아, 느립니다. 루프 (복사 기능으로 함축 됨)가 있기 때문에 각 요소는 개별적으로 처리되어야합니다. 배열과 벡터가 연속적인 블록이라는 사실을 기반으로 성능을 향상시킬 수 없습니다.

방법 2방법 1 에 대해 제안 된 성능 향상입니다. 추가하기 전에 배열의 크기를 미리 예약하십시오. 큰 배열의 경우 도움 이 수 있습니다. 그러나 여기서 가장 좋은 조언은 프로파일 링에서 개선을 얻을 수 있다고 제안하지 않는 한 예약을 사용하지 않는 것입니다 (또는 반복기가 무효화되지 않도록해야 함). Bjarne은 동의합니다 . 덧붙여서, 나는이 방법 이 방법 1보다 규칙적으로 현저히 느린 이유를 포괄적으로 설명하기 위해 애 쓰고 있지만 대부분의 시간 이 가장 느리다 는 것을 발견했습니다 …

방법 3 은 구식 해결책입니다. 문제에 C를 던져보세요! POD 유형에 대해 빠르고 잘 작동합니다. 이 경우 memcpy가 벡터의 경계 밖에서 작동하고 크기가 변경되었음을 벡터에 알릴 방법이 없기 때문에 resize를 호출해야합니다. 추악한 솔루션 (바이트 복사!)과는 별개 로 POD 유형에만 사용할 수 있음을 기억하십시오 . 이 솔루션을 사용하지 않을 것입니다.

방법 4 가 가장 좋은 방법입니다. 의미가 명확하고 (보통) 가장 빠르며 모든 개체에 대해 작동합니다. 이 응용 프로그램에이 방법을 사용하는 데 단점이 없습니다.

방법 5 는 방법 4에 대한 조정입니다. 배열을 벡터에 복사 한 다음 추가합니다. 좋은 옵션-일반적으로 빠르고 명확합니다.

마지막으로, 배열 대신 벡터를 사용할 수 있다는 것을 알고 계십니까? 함수가 c 스타일 배열을 예상하는 경우에도 벡터를 사용할 수 있습니다.

vector<char> v(50); // Ensure there's enough space
strcpy(&v[0], "prefer vectors to c arrays");

누군가가 도움이되기를 바랍니다!


답변

수행중인 모든 작업이 기존 데이터를 교체하는 것이라면이를 수행 할 수 있습니다.

std::vector<int> data; // evil global :)

void CopyData(int *newData, size_t count)
{
   data.assign(newData, newData + count);
}


답변

std :: copy 는 당신이 찾고있는 것입니다.


답변

내 답변 만 수정할 수 있으므로 내 질문에 대한 다른 답변에서 복합 답변을 만들 것입니다. 답변 해주신 모든 분들께 감사드립니다.

std :: copy를 사용 하면 여전히 백그라운드에서 반복되지만 코드를 입력 할 필요는 없습니다.

int foo(int* data, int size)
{
   static std::vector<int> my_data; //normally a class variable
   std::copy(data, data + size, std::back_inserter(my_data));
   return 0;
}

일반 memcpy 사용 . 이것은 아마도 기본 데이터 유형 (예 : int)에 가장 잘 사용되지만 더 복잡한 구조체 또는 클래스 배열에는 사용되지 않습니다.

vector<int> x(size);
memcpy(&x[0], source, size*sizeof(int));


답변

memcpy를 피하십시오. 꼭 필요한 경우가 아니면 포인터 작업을 엉망으로 만들 이유가 없습니다. 또한 int와 같은 POD 유형에서만 작동하지만 구성이 필요한 유형을 처리하는 경우 실패합니다.


답변

int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//source

unsigned dataArraySize = sizeof(dataArray) / sizeof(int);

std::vector<int> myvector (dataArraySize );//target

std::copy ( myints, myints+dataArraySize , myvector.begin() );

//myvector now has 1,2,3,...10 :-)