Невозможно использовать .begin() или .end() в массиве - программирование
Подтвердить что ты не робот

Невозможно использовать .begin() или .end() в массиве

Ошибка:

запрос для члена 'begin', 'end' в 'arr', который не является типом класса int [5], не удалось вывести из ошибки выражения.

Мой код:

#include <iostream>
using namespace std;

int main()
{
    int * mypointer;

    int arr[5] = {1,3,5,7,9};

    mypointer = arr;

    for(auto it = arr.begin(); it != arr.end(); ++it) {
        cout<<*mypointer<<endl;

        mypointer++;
    }

    return 0;
}
4b9b3361

Ответ 1

Массивы не имеют функций-членов, поскольку они не являются типом класса. Это то, о чем говорит ошибка.

Вместо <iterator> можно использовать std::begin(arr) и std::end(arr). Это также работает с типами, которые имеют элементы .begin() и .end(), путем перегрузки:

#include <array>
#include <vector>

#include <iterator>

int main()
{
    int c_array[5] = {};
    std::array<int, 5> cpp_array = {};
    std::vector<int> cpp_dynarray(5);

    auto c_array_begin = std::begin(c_array); // = c_array + 0
    auto c_array_end = std::end(c_array);     // = c_array + 5

    auto cpp_array_begin = std::begin(cpp_array); // = cpp_array.begin()
    auto cpp_array_end = std::end(cpp_array);     // = cpp_array.end()

    auto cpp_dynarray_begin = std::begin(cpp_dynarray); // = cpp_dynarray.begin()
    auto cpp_dynarray_end = std::end(cpp_dynarray);     // = cpp_dynarray.end()
}

Ответ 2

В С++ массивы не являются классами и поэтому не имеют каких-либо методов-членов. Они ведут себя как указатели в некоторых контекстах. Вы можете воспользоваться этим, изменив свой код:

#include <iostream>
using namespace std;

int main()
{
    int * mypointer;

    const int SIZE = 5;
    int arr[SIZE] = {1,3,5,7,9};

    mypointer = arr;

    for(auto it = arr; it != arr + SIZE; ++it) {
        cout<<*mypointer<<endl;

        mypointer++;
    }

    return 0;
}

Конечно, это означает, что mypointer и it оба содержат один и тот же адрес, поэтому вам не нужны оба из них.

Ответ 3

Для стандартного массива C с фиксированной длиной вы можете просто написать

int c_array[] = {1,3,5,7,9}, acc = 0;

for (auto it : c_array) {
    acc += it;
}

Компилятор выполняет за кадром работу, устраняя необходимость создания всех этих итераторов начала и конца.

Ответ 4

Одна вещь, которую я хотел бы отметить для вас, это то, что вам действительно не нужно поддерживать отдельный int * для использования при разыменовании элементов массива, кроме всего того, что другие люди хорошо указали.

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

#include <iostream>
#include <algorithm>
#include <array>
#include <iterator>
using namespace std;

int main()
{
    std::array<int, 5> cpp_array{1,3,5,7,9};

    // Simple walk the container elements.
    for( auto elem : cpp_array )
        cout << elem << endl;

    // Arbitrary element processing on the container.
    std::for_each( begin(cpp_array), end(cpp_array), [](int& elem) {
        elem *= 2;      // double the element.
        cout << elem << endl;
    });
}

Использование lambda во втором примере позволяет вам удобно выполнять произвольную обработку элементов, если это необходимо. В этом примере я просто показываю удвоение каждого элемента, но вы можете сделать что-то более значимое внутри тела лямбды.

Надеюсь, это имеет смысл и помогает.

Ответ 5

Возможно, здесь есть более чистый способ сделать это, используя шаблоны и lambdas в С++ 14:

Определить:

template<typename Iterator, typename Funct>
void my_assign_to_each(Iterator start, Iterator stop, Funct f) {
    while (start != stop) {
        *start = f();
        ++start;
    }
}

template<typename Iterator, typename Funct>
void my_read_from_each(Iterator start, Iterator stop, Funct f) {
    while (start != stop) {
        f(*start);
        ++start;
    }
}

И затем в основном:

int x[10];
srand(time(0));
my_assign_to_each(x, x+10, [] () -> int { int rn{}; rn = rand(); return rn; });
my_read_from_each(x, x+10, [] (int value) { std::cout << value << std::endl; });

int common_value{18};
my_assign_to_each(x, x+10, [&common_value] () -> int { return common_value; });
my_read_from_each(x, x+10, [] (int value) { std::cout << value << std::endl; });