web-dev-qa-db-fra.com

Impossible d'utiliser .begin () ou .end () sur un tableau

L'erreur lit:

demande du membre 'begin', 'end' in 'arr' qui n'est pas un type de classe int [5], impossible de déduire d'une erreur d'expression.

Mon code:

#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;
}
20
Sal Rosa

Les tableaux n'ont pas de fonctions membres car ils ne sont pas un type de classe. C'est ce que dit l'erreur.

Vous pouvez plutôt utiliser std::begin(arr) et std::end(arr) à partir de l'en-tête <iterator>. Ceci fonctionne aussi avec les types qui ont ont les membres .begin() et .end(), via surcharge:

#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()
}
40
GManNickG

Pour un tableau C standard de longueur fixe, vous pouvez simplement écrire

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

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

Le compilateur effectue le travail en arrière-plan, éliminant ainsi la nécessité de créer tous ces itérateurs de début et de fin.

3
user1329482

En C++, les tableaux sont pas classes et n'ont donc pas de méthodes any member. Ils se comportent comme des pointeurs dans certains contextes. Vous pouvez en tirer parti en modifiant votre code:

#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;
}

Bien entendu, cela signifie que mypointer et it contiennent tous deux la même adresse, vous n’avez donc pas besoin des deux.

1
Code-Apprentice

Assez tard mais je pense qu'il vaut la peine de mentionner que:

void findavgTime(int n)
{
    int wt1[n];
    fill_wt(wt1,n); //Any method that puts the elements into wt1
    int wt2[3];
    int sum  = accumulate(begin(wt1), end(wt1), 0); // Fails but wt2[3] will pass. Reason: variable-sized array type ‘int [n]’ is not a valid template argument)
}
0
Roshan Mehta

Peut-être voici une façon plus simple de le faire en utilisant des modèles et des lambdas dans c ++ 14:

Définir:

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;
    }
}

Et puis en gros:

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; });
0
Jeff Moellmer

Une chose que je voudrais souligner pour vous est que vous n’avez vraiment pas besoin de conserver un int * séparé pour utiliser le déréférencement des éléments du tableau, mis à part le membre entier que les autres ont bien souligné.

En utilisant une approche plus moderne, le code est à la fois plus lisible et plus sûr:

#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;
    });
}

L'utilisation du lambda dans le deuxième exemple vous permet d'effectuer facilement un traitement arbitraire sur les éléments, si nécessaire. Dans cet exemple, je montre simplement le doublement de chaque élément, mais vous pouvez faire quelque chose de plus significatif dans le corps lambda.

J'espère que cela a du sens et aide.

0
Herpin the Derps