2017-01-16 1 views
2

Я хотел бы инициализировать boost :: multi_array inline в некотором коде. Но я не думаю, что 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

@ Этот вопрос связан с созданием multi_array с определенными РАЗМЕРЫ. Мой вопрос о создании multi_array с определенным СОДЕРЖАНИЕМ. –

ответ

1

В приведенном ниже примере из официальной дополнительной документации относительно multi_array используется также memcpy, хотя в сочетании с origin(). Так что, кажется, в порядке его использования:

#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'; 
} 

Что касается разницы между origin() и data(), то multiarray reference manual определяет следующее:

элемента * данных(); Это возвращает указатель на начало смежного блока , который содержит данные массива. Если все размеры , массив 0-индексируется и сохраняется в порядке возрастания, это эквивалентно origin().

элемент * происхождение(); Это возвращает элемент origin из multi_array.

Так что, кажется, две вещи, которые необходимо учитывать при использовании data() и origin() вместе с memcpy, далее массив содержит размеры, которые не 0-индексированные или не в порядке возрастания:

во-первых, origin() не может указывают на начало блока непрерывной памяти, используемого массивом. Следовательно, копирование памяти в размере многоадресного объекта в это место может превышать зарезервированный блок памяти.

Во-вторых, копирование блока памяти на адрес data() может привести к расположению памяти, где индексы массивов, доступные через многоадресную рассылку, не соответствуют индексам блока памяти, скопированным во внутренний буфер данных массива ,

Так что мне кажется, что с использованием memcpy в (pre) -заполнение мультиматрицы должно использоваться с осторожностью и в идеале с индексами на основе 0 и по возрастанию.

+0

Если внутренний порядок массива не возрастает, ни data(), ни origin() не могут спасти вас от того, что здесь будет делать memcpy(). В этом случае вам понадобятся некоторые циклы или итераторы. В противном случае, я предпочитаю origin(), потому что я ожидаю, что элемент [0] [0] моего примитивного временного элемента окажется в позиции [0] [0] для multi_array. Внезапно я думаю, что, возможно, мне действительно нужно использовать std :: copy здесь, а не memcpy. –

 Смежные вопросы

  • Нет связанных вопросов^_^