Обычное предложение использовать адаптер с мелкими массивами кажется мне саркастичным - чтобы иметь возможность просто получить доступ к массиву через указатель, вы должны поместить его в shared_array со всеми шебангами для подсчета ссылок (которые ни к чему не приводят) , поскольку у вас нет массива) и, что более важно, с кошмаром псевдонимов данных.
На самом деле, uBLAS имеет полноценную реализацию хранилища (array_adaptor
), которая позволяет использовать векторы с внешними массивами c. Единственный улов - векторный конструктор, который делает копию. Почему эта замечательная функция не используется в библиотеке, мне совершенно не понятно, но в любом случае мы можем использовать небольшое расширение (на самом деле это 2 строки кода, окруженные обычным раздутием c ++)
template<class T>
class extarray_vector :
public vector<T, array_adaptor<T> >
{
typedef vector<T, array_adaptor<T> > vector_type;
public:
BOOST_UBLAS_INLINE
extarray_vector(size_type size, pointer p)
{ data().resize(size, p); }
template <size_type N>
BOOST_UBLAS_INLINE
extarray_vector(T (&a)[N])
{ data().resize(N, a); }
template<class V>
BOOST_UBLAS_INLINE
extarray_vector& operator = (const vector<T, V>& v)
{
vector_type::operator = (v);
return *this;
}
template<class VC>
BOOST_UBLAS_INLINE
extarray_vector& operator = (const vector_container<VC>& v)
{
vector_type::operator = (v);
return *this;
}
template<class VE>
BOOST_UBLAS_INLINE
extarray_vector& operator = (const vector_expression<VE>& ae)
{
vector_type::operator = (ae);
return *this;
}
};
вы можете использовать его так:
int i[] = {1, 4, 9, 16, 25, 36, 49};
extarray_vector<int> iv(i);
BOOST_ASSERT_MSG(i == &iv[0], "Vector should attach to external array\n");
iv[3] = 100;
BOOST_ASSERT(i[3] == 100);
iv.resize(iv.size() + 1, true);
BOOST_ASSERT_MSG(i != &iv[0], "And detach from the array on resize\n");
iv[3] = 200;
BOOST_ASSERT(i[3] == 100);
iv.data().resize(7, i, 0);
BOOST_ASSERT_MSG(i == &iv[0], "And attach back to the array\n");
BOOST_ASSERT(i[3] == 200);
Вы можете динамически присоединять и отсоединять вектор к внешнему хранилищу с помощью метода resize array_adaptor (сохранение или удаление данных). При изменении размера он автоматически отсоединяется от хранилища и становится обычным вектором. Присвоение из контейнеров отправляется непосредственно в хранилище, но присваивание из выражения выполняется через временное хранилище, а вектор отсоединяется от хранилища, используйте noalias()
, чтобы предотвратить это. В конструкторе есть небольшие накладные расходы, так как data_ является приватным членом, и мы должны по умолчанию инициализировать его с новым T [0], а затем переназначить во внешний массив. Вы можете изменить его на защищенный и назначить для хранения непосредственно в конструкторе.