Получение ссылки на разыменованный элемент из контейнера указателей по диапазонному циклу

Дано контейнер указателей на ints, как я могу увеличить intбез использования оператора разыменования * в теле цикла {}?

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

#include <vector>
#include <iostream>
using namespace std;

int main() {
int x = 0, y = 1, z = 2;

auto increment_elements = [](vector<int*>& v) {
for (auto& i : v) { ++*i };
};

increment_elements(vector<int*>{&x, &y, &z});

cout << x << ", " << y << ", " << z << endl;
}

Замена

for (auto& i : v) { ++*i };

с

for (int& i : v) { ++i };

дает MSVC-2013

error C2440: 'initializing' : cannot convert from 'int *' to 'int &',

Почему замена с

for (auto& i : v) { ++i };

компилировать, но не увеличивая intс, а что это делает?

У меня такой же вопрос относительно замены на

for (int*& i : v) ++i;

что дает тот же результат.

0

Решение

Учитывая контейнер указателей на целые, как я могу увеличивать целые без использования оператора разыменования * в теле цикла {}?

Использует ссылки на указатели, когда вы можете. Вы не можете сделать вектор ссылочного типа, поэтому вы можете использовать std::reference_wrapper<int>,

std::vector<std::reference_wrapper<int>> v{x, y, z};

increment_elements Вероятно, следует также взять диапазон, чтобы соответствовать общему программированию. Тогда используйте get() на элементы и увеличивать их:

template<class Iter>
void increment_elements(Iter first, Iter last)
{
for (; first != last; ++first->get(), ++first);
}

Тогда вы можете позвонить, используя begin() а также end():

increment_elements(std::begin(v), std::end(v));

Или, если вы все еще хотите взять вектор в качестве аргумента, вы можете просто выполнить итерации и увеличить:

for (int& i : v) ++i;

и назовите это как:

increment_elements(v);

Почему замена на […] компилируется, но без увеличения числа int, и что она делает?

auto выводит тип элемента как int* так decltype(i) становится int*& который делает то же самое, что и ваш последний пример.

1

Другие решения

Ваш вектор vector<int *>, не vector<int>!

vector<int *> &v;
for (auto &i : v)
++(*i);

v это вектор int *, Итак, тип i является int* &, Поэтому вы должны использовать ++(*i); увеличивать x, y а также z,

for (int &i : v)
++i;

Это не верно. v это вектор int *, но вы пытаетесь назначить int * в int &,

for (auto &i : v)
++i;

Этот код увеличивается указатели, не x, y, z, Поскольку он равен

for (std::vector<int *>::iterator it = v.begin(); it != v.end(); ++it)
++(*it);
0

По вопросам рекламы [email protected]