web-dev-qa-db-ja.com

配列では.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;
}
23
Sal Rosa

配列はクラス型ではないため、メンバー関数はありません。これがエラーの意味です。

代わりに_<iterator>_ヘッダーのstd::begin(arr)およびstd::end(arr)を使用できます。これは、オーバーロードを介してdo.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()
}
_
44
GManNickG

標準の固定長C配列の場合、次のように記述できます。

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

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

コンパイラーは舞台裏での作業を行うため、これらの開始および終了イテレーターをすべて作成する必要がなくなります。

3
user1329482

C++では、配列はnotクラスであるため、anyメンバーメソッドはありません。一部のコンテキストではポインターのように動作します。これを利用するには、コードを変更します。

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

もちろん、これはmypointeritの両方が同じアドレスを含むことを意味するため、両方を必要としません。

1
Code-Apprentice

かなり遅れていますが、言及する価値があると思います:

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

おそらくここに、c ++ 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; });
0
Jeff Moellmer

私があなたに指摘したいことの1つは、他の人がよく指摘しているメンバー全体のものとは別に、配列要素の逆参照に使用するために別個の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;
    });
}

2番目の例でラムダを使用すると、必要に応じて、要素に対して任意の処理を簡単に実行できます。この例では、各要素を2倍にすることを示していますが、代わりにラムダ本体内でより意味のある何かを行うことができます。

これが理にかなって助けになることを願っています。

0