Как построить начальный и конечный итераторы в середине массива? - PullRequest
1 голос
/ 12 мая 2019

Я пытаюсь перевернуть часть массива на месте, используя std :: reverse, который занимает два итератора. Когда я пытаюсь построить итераторы следующим образом:

int a[] = {0, 1, 2, 3, 4, 5, 6};
reverse(begin(a + 2), end(a + 4));

Я получаю сообщение об ошибке:

template argument deduction/substitution failed:
test.cpp:8:33: note:   mismatched types ‘const std::valarray<_Tp>’ and ‘int*’ reverse(begin(a + 2), end(a + 4));

Как правильно построить итераторы?

Ответы [ 2 ]

5 голосов
/ 12 мая 2019

std::begin и std::end - это функции, которые принимают контейнер и дают вам итераторы, указывающие на первый и один за другим элементы соответственно.

std::begin и std::end сами по себе не являются итераторами, и они не работают с необработанными указателями, поскольку указатели не имеют никакой информации о размере. При вызове std::begin(a+2), a распадается на указатель на свой первый элемент и сдвигается на 2 элемента. Полученный указатель передается в std::begin, но std::begin не работает с указателями, поэтому результатом является ошибка компиляции.

Чтобы решить вашу проблему, просто избавьтесь от звонков на std::begin и std::end:

std::reverse(a+2, a+4);

Это работает, поскольку указатели удовлетворяют всем требованиям для итератора, поэтому указатели, следующие из a+2 и a+4, полностью действительны для передачи в std::reverse.

2 голосов
/ 12 мая 2019

Мили - это правильно.

Но, если вам нужны итераторы по какой-то другой причине (скажем, это не всегда будет массив), вы можете сделать это.

Вам просто нужно увеличить итератор, а не массив, из которого вы его строите:

reverse(begin(a) + 2, begin(a) + 4);

(Вы также написали end, когда я думаю, что вы имели в виду begin!)

...