2015-03-19 3 views
0

У меня проблема с std :: fill.Заполнить двумерный массив объектов C++

Сначала я определяю двумерный массив пар.

const int NMAX = 13;                
typedef pair<int, set<int>> solution;            
solution memo[NMAX][NMAX];  

Я предполагаю, что на этом этапе мой массив инициализируется конструктором пары по умолчанию. Затем я хотел бы инициализировать этот массив, не полагаясь на вложенный цикл. Что я делаю так:

solution s;                 
s.first = -1;                         
std::fill(&memo[0][0], &memo[0][0] + sizeof(memo), s); 

Но я получаю ошибку в автобусе ... Что я делаю неправильно?

+2

_theolution memo [NMAX] [NMAX]; '_ why not' vector > memo; 'вместо этого? Также 'array , MAX> memo;' должно быть в порядке. –

+3

'sizeof' - это не количество элементов, а количество символов (байтов). –

+0

@ πάνταῥεῖ Не то же самое. Данные в векторе векторов не смежны. – juanchopanza

ответ

2

Ваш конец указателя является неправильным, вы имели в виду:

std::fill(&memo[0][0], &memo[0][0] + sizeof(memo)/sizeof (solution), s); 

в sizeof(memo) является NMAX * NMAX * sizeof (solution).

+0

Я уверен, что в этом есть что-то вроде UB, потому что он обращается к внешнему массиву за пределами границ. См. Http://stackoverflow.com/questions/7269099/may-i-treat-a-2d-array-as-a-contiguous-1d-array – juanchopanza

+0

Технически это UB; он делает то же самое, что и «memo [0] [NMAX] = s; memo [0] [NMAX + 1] = s; 'и т. д. –

+0

@juanchopanza Соответствующий раздел в стандарте четко не сформулирован.Неясно, может ли «элемент объекта массива» быть «int» в этом случае. Если вы говорите «Нет, это не может», тогда многие общепринятые методы становятся незаконными (например, итерация над «записью» с помощью символа 'char *'). Моя интерпретация заключается в том, что законно использовать 'int *' для итерации по массиву, пока вы формируете его с помощью '(int *) & memo' или' (int *) & memo [0] ', так что« массив объект "однозначно означает' memo', а не под-объект 'memo'. –

1

На самом деле мы можем сделать все это намного проще с std::vector:

typedef pair<int, set<int>> solution; 
solution s;                 
s.first = -1; 
std::vector<std::vector<solution>> memo(NMAX, std::vector<solution>(NMAX, s)); 

Live Demo

Если у вас есть некоторые ограничения против использования std::vector, это будет гораздо легче работать с чем делая кучу указателя математики.

Редактировать: Это не худшая идея использовать std::array, как и πάντα ῥεῖ. Вы можете избежать написания внутреннего цикла для выполнения самостоятельно заполняют std::for_each следующим образом:

std::array<std::array<solution, NMAX>, NMAX> memo; 
solution s;                 
s.first = -1; 
std::for_each(std::begin(memo), std::end(memo), [&s](std::array<solution,NMAX>& next){next.fill(s);}) 

Demo 2

Edit 2: Если вы действительно мазохистской и хотите, чтобы вычислить [строка] [столбец ] индексы сами, то вы можете использовать один std::array<solution, NMAX*NMAX> и воспользоваться std::begin() и std::end() позвонить std::fill:

std::array<solution, NMAX*NMAX> memo; 
solution s;                 
s.first = -1; 
std::fill(std::begin(memo),std::end(memo), s); 

Demo 3

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