2017-01-16 8 views
2

일부 코드에서 boost :: multi_array 인라인을 초기화하고 싶습니다. 하지만 boost :: multi_array 이니셜 라이저 목록에서 초기화를 지원한다고 생각하지 않습니다. 여기에 지금까지이 작업은 다음과 같습니다초기화 도구 목록에서 boost :: multi_array를 채우는 가장 좋은 방법은 무엇입니까?

// First create a primitive array, which can be directly initialized 
uint8_t field_primitive[4][8] = { 
    { 1,1,1,1,1,1,1,1 }, 
    { 1,2,1,2,1,2,1,2 }, 
    { 1,1,2,2,2,2,2,2 }, 
    { 1,2,2,2,2,2,2,2 } 
}; 
// Create the boost::multi_array I actually want to use 
boost::multi_array<uint8_t, 2> field(boost::extents[4][8]); 
// Compact but yucky approach to copying the primitive array contents into the multi_array. 
memcpy(field.data(), field_primitive, field.num_elements() * sizeof(uint8_t)); 

내가 콤팩트 중괄호 intializer 목록을 사용하여 매트릭스의 내용을 표현할 수있는 것을 좋아한다. 하지만 "memcpy"가 마음에 들지 않아 원시 배열을 사용하는 것을 좋아하지 않습니다. 코드에서 값의 읽기 가능한 인라인 집합에서 boost :: multi_array를 채울 수있는 더 좋은 방법이 있습니까?

+0

아마도 여기 뭔가가 도움이 될까요? http://stackoverflow.com/questions/8824247/one-line-initialiser-for-boost-multiarray – Tas

+0

thecppboostlibraries의 다음 링크는'origin()'과'memcpy'를 사용한 예제입니다 : https://theboostcpplibraries.com /boost.multiarray –

+0

@ 특정 DIMENSIONS가있는 다중 배열을 만드는 것과 관련하여 연결된 질문이 있습니다. 내 질문에 대한 특정 내용으로 multi_array 만드는 방법에 대한 것입니다. –

답변

1

multi_array과 관련된 공식적인 부스트 문서의 다음 예제는 origin()과 결합하여 memcpy을 사용합니다. multiarray reference manual 다음 정의 origin()data()와의 차이에 관한

#include <boost/multi_array.hpp> 
#include <algorithm> 
#include <iostream> 
#include <cstring> 

int main() 
{ 
    boost::multi_array<char, 2> a{boost::extents[2][6]}; 

    typedef boost::multi_array<char, 2>::array_view<1>::type array_view; 
    typedef boost::multi_array_types::index_range range; 
    array_view view = a[boost::indices[0][range{0, 5}]]; 

    std::memcpy(view.origin(), "tsooB", 6); 
    std::reverse(view.begin(), view.end()); 

    std::cout << view.origin() << '\n'; 

    boost::multi_array<char, 2>::reference subarray = a[1]; 
    std::memcpy(subarray.origin(), "C++", 4); 

    std::cout << subarray.origin() << '\n'; 
} 

: 그래서 그것을 사용 OK 보인다

* 데이터 요소(); 이 배열의 데이터가 들어있는 인접한 블록의 시작 부분에 대한 포인터를 반환합니다. 의 모든 차원이 0 인덱싱되고 오름차순으로 저장된 경우이 값은 이고 origin()과 같습니다.

요소 * origin(); multi_array의 원점 요소를 반환합니다.

그래서 memcpy와 함께 data()origin()를 사용하는 경우 배열이 오름차순으로 0 인덱스 여부되지 않는 차원이 포함되어 FF로, 고려해야 할 두 가지가있을 것 같다 :

먼저, origin()은 그렇지 않을 수 있습니다 배열에서 사용하는 연속 메모리 블록의 시작을 가리 킵니다. 따라서, 멀티 어레이의 크기로 메모리를이 위치로 복사하는 것은 예약 된 메모리 블록을 초과 할 수 있습니다.

두 번째로, 메모리 블록을 data()의 주소로 복사하면 다중 배열을 통해 액세스 된 배열 인덱스가 배열의 내부 데이터 버퍼에 복사 된 메모리 블록의 indizes와 일치하지 않는 메모리 레이아웃이 발생할 수 있습니다 .

memcpy을 사용하면 multiarray가 0 기반 인덱스와 오름차순으로 이상적으로 사용되어야합니다.

+0

배열 내부 순서가 오름차순이 아닌 경우, data() 나 origin()도 memcpy()가 여기서 수행 할 작업에서 사용자를 구할 수 없습니다. 이 경우 일부 루프 또는 반복기가 필요합니다. 그렇지 않으면 origin (0)이 원시 배열의 요소 [0] [0]이 multi_array [0] [0]에 위치 할 것으로 기대하기 때문에 origin()을 선호합니다. 갑자기 나는 아마도 memcpy보다는 std :: copy를 사용해야한다고 생각한다. –