不能在数组上使用 .begin() 或 .end()
Cannot use .begin() or .end() on an array
错误为:
请求成员"开始","结束"中的"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;
}
数组
没有成员函数,因为它们不是类类型。这就是错误所说的。
您可以改用<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()
}
对于标准的固定长度 C 数组,你可以只写
int c_array[] = {1,3,5,7,9}, acc = 0;
for (auto it : c_array) {
acc += it;
}
编译器完成后台工作,无需创建所有这些开始和结束迭代器。
在C++中,数组不是类,因此没有任何成员方法。在某些情况下,它们的行为确实像指针。您可以通过修改代码来利用这一点:
#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
都包含相同的地址,因此您不需要它们。
我想为您指出的一件事是,除了其他人已经很好地指出的整个成员之外,您真的不必维护一个单独的 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 可以方便地对元素执行任意处理。在这个例子中,我只是展示了将每个元素加倍的过程,但你可以在 lambda 体内做一些更有意义的事情。
希望这是有道理的,有帮助。
也许这里有一种更简洁的方法,可以在 c++14 中使用模板和 lambda:
定义:
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; });
很晚了,但我认为值得一提的是:
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)
}
相关文章:
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- remove(str.begin(), str.end(), );无法正常工作(我正在使用视觉工作室 2012)
- 了解向量中的 .begin 和 .end
- C++ const char with .begin() and .end()
- 为什么 std::find( s.begin(), s.end(), val ) 比集合 s 的 s.find(val) 慢 1000 倍<int>?
- 如何使用vector.begin()和vector.end()遍历矩阵?
- 如何实现 cbegin() 和 cend() 从 begin() 和 end() ?
- C++ - 空的 std::list begin() 和 end() 不相等
- 为什么std::begin()和std::end()适用于固定数组,而不适用于动态数组
- C++代码"x.erase(std::remove(x.begin(), x.end(), ), x.end())"是如何工作的?
- begin(),end()和cbegin(),cend()之间的区别是什么?
- 在模板化数据结构上调用 begin() 或 end()
- 重载 std::begin() 和 std::end() 用于非数组
- 使用 std::set 的 .begin() 和 .end() 函数会产生意想不到的结果
- 使用范围V3视图来实现begin()/end()方法
- 为 C++ 选择 begin() 和 end()
- std::begin() 和 std::end() 不适用于类中的未知长度数组
- 在 std::list 中,std::d istance(it.begin(), std::p rev(it.end()
- 使用迭代器的二叉搜索,为什么我们使用"(end - begin)/2"?