2017-02-12 3 views
1

Я пытаюсь использовать boost для создания многомерного массива, и я хочу, чтобы указанный массив был членом некоторого класса.boost multiarray как член класса не заполнен

Однако я нахожу две проблемы с ним: 1 - Мне нужно, чтобы объявить размер массива с

boost::extents[2][2] 

Everytime Я хочу использовать массив. В противном случае я получаю следующее сообщение об ошибке:

a.out: /usr/include/boost/multi_array/base.hpp:136: Referenceboost::detail::multi_array::value_accessor_n<T, NumDims>::access(boost::type<Reference>, boost::detail::multi_array::value_accessor_n<T, NumDims>::index, TPtr, const size_type*, const index*, const index*) const [with Reference = boost::detail::multi_array::sub_array<double, 1ul>; TPtr = double*; T = double; long unsigned int NumDims = 2ul; boost::detail::multi_array::value_accessor_n<T, NumDims>::index = long int; boost::detail::multi_array::multi_array_base::size_type = long unsigned int]: Assertion `size_type(idx - index_bases[0]) < extents[0]' failed. 

2 - Хорошо, может быть, это только часть того, как многомерные массивы работают в C++ с Boost, я собираюсь написать свой код, принимающие все функции «объявляет» массив. Однако, если я это сделаю, я обнаружил, что массив пуст.

Вот фрагмент кода, который воспроизводит эту проблему. Во время «построения» класса массив должен быть заполнен. Однако линия

cout << "Result: " << testing.getArrayMember(0,1) << endl; 

выходы «Результат: 0».

#include <iostream> 
#include "boost/multi_array.hpp" 
typedef boost::multi_array<double, 2> dbl_array; 

using namespace std; 

class TestClass { 
    public: 
     dbl_array darray; 
     TestClass(double x); 
     void fillArray(double x); 
     double getArrayMember(int i, int j); 
}; 

TestClass::TestClass(double x) { 
    dbl_array darray(boost::extents[2][2]); 
    cout << "Class constructor called" << endl; 
    fillArray(x); 
} 

void TestClass::fillArray(double x) { 
    cout << "Filling array" << endl; 
    dbl_array darray(boost::extents[2][2]); // Without this line, the code  fails at runtime 
    darray[0][0] = x; 
    darray[1][0] = 2.0*x; 
    darray[0][1] = 3.0*x; 
    darray[1][1] = 4.0*x; 
    cout << "Array filled" << endl; 
} 

double TestClass::getArrayMember(int i, int j) { 
    dbl_array darray(boost::extents[2][2]); // Without this line, the code  fails at runtime 
    return darray[i][j]; 
} 

int main() { 

    TestClass testing = TestClass(5.0); 

    // The result is 0 in the end 
    cout << "Result: " << testing.getArrayMember(0,1) << endl; 
    return 0; 
} 

Что я здесь делаю неправильно?

ответ

0

Вариант 1 является использование списка инициализации:

TestClass::TestClass(double x) : darray(boost::extents[2][2]) { 
    cout << "Class constructor called" << endl; 
    fillArray(x); 
} 

Поскольку в противном случае член класса DArray создается с помощью конструктора по умолчанию, а не через линию

dbl_array darray(boost::extents[2][2]); 

как вы верите.

Это одни и те же ответы, как указано в initialize boost::multi_array in a class

Однако, я хочу добавить следующий бит, который я думаю, что это имеет отношение в этой ситуации:

Это может быть необходимо для Вас, чтобы генерировать массив после выполнения какой-либо операции в конструкторе вашего класса. Вы можете достичь этого, используя «resize» после того, как массив был создан конструктором по умолчанию.

Т.е., вместо

TestClass::TestClass(double x) { 
    dbl_array darray(boost::extents[2][2]); 
    cout << "Class constructor called" << endl; 
    fillArray(x); 
} 

вы могли бы

TestClass::TestClass(double x) { 
    darray.resize(boost::extents[2][2]); 
    cout << "Class constructor called" << endl; 
    fillArray(x); 
} 
+0

это решило проблему, спасибо – user7311356