C++ 基于范围的动态数组上的循环?

C++ 基于范围的动态数组上的循环?,c++,arrays,c++11,foreach,dynamic-arrays,C++,Arrays,C++11,Foreach,Dynamic Arrays,有一个基于范围的for循环,语法如下: for(auto& i : array) 它适用于常量数组,但不适用于基于指针的动态数组,如 int *array = new int[size]; for(auto& i : array) cout<< i << endl; int*array=newint[size]; 用于(自动输入:阵列(&i) cout您不能对动态分配的数组使用range for循环,因为编译器无法推断该数组的开始和结束。例如,您

有一个基于范围的for循环,语法如下:

for(auto& i : array)
它适用于常量数组,但不适用于基于指针的动态数组,如

int *array = new int[size];
for(auto& i : array)
   cout<< i << endl;
int*array=newint[size];
用于(自动输入:阵列(&i)

cout您不能对动态分配的数组使用range for循环,因为编译器无法推断该数组的开始和结束。例如,您应该始终使用容器而不是它

std::向量v(大小);
用于(常量自动和元素:v)
//做点什么

您不能直接在动态分配的数组上执行基于范围的循环,因为您只有指向第一个元素的指针。没有编译器可以用来执行循环的关于其大小的信息。惯用的C++解决方案是用<代码> STD::vector < /代码>:< /P>替换动态分配的数组。
std::vector<int> arr(size);
for(const auto& i : arr)
  std::cout<< i << std::endl;
但在这两种情况下,大小都需要是编译时常量。

要使用基于范围的for循环,必须提供
begin()
end()
成员函数或重载非成员
begin()
end()
函数。 在后一种情况下,您可以将范围包装在
std::pair
中,并重载
begin()
end()

    namespace std {
        template <typename T> T* begin(std::pair<T*, T*> const& p)
        { return p.first; }
        template <typename T> T* end(std::pair<T*, T*> const& p)
        { return p.second; }
    }
您的呼叫站点如下所示:

    for (auto&& i : std::make_pair(array, array + size))
        cout << i << endl;
    for (auto&& i : wrap_array(array, size))
         std::cout << i << std::endl;
#include <iostream>
#include <span>

int main () {
    auto p = new int[5];
    for (auto &v : std::span(p, 5)) {
        v = 1;
    }
    for (auto v : std::span(p, 5)) {
        std::cout << v << '\n';
    }
    delete[] p;
}
for(自动(&i:wrap_数组(数组,大小))
std::coutC++20将(大概)添加,这允许如下循环:

    for (auto&& i : std::make_pair(array, array + size))
        cout << i << endl;
    for (auto&& i : wrap_array(array, size))
         std::cout << i << std::endl;
#include <iostream>
#include <span>

int main () {
    auto p = new int[5];
    for (auto &v : std::span(p, 5)) {
        v = 1;
    }
    for (auto v : std::span(p, 5)) {
        std::cout << v << '\n';
    }
    delete[] p;
}
#包括
#包括
int main(){
自动p=新整数[5];
用于(自动&v:std::span(第5页)){
v=1;
}
用于(自动v:std::span(p,5)){

std::cout而不是为
std::pair
指针定义
std::begin
std::end
(顺便说一句,在
std:
中定义它们)并推出您自己的包装器,因为您可以使用
boost::make\u iterator\u range

size_t size = 16;
int *dynamic_array = new int[size];
for (const auto& i : boost::make_iterator_range(dynamic_array, dynamic_array + size))
    std::cout << i << std::endl;
size\u t size=16;
int*动态数组=新int[大小];
for(const auto&i:boost::make_iterator_range(动态数组,动态数组+大小))

STD::什么是错误?至少一个错误,它叫做Reland for Roop,谷歌有很多例子,第二个例子是一个打印错误。应该是<代码>(Auto&I:ARR)< /COD>不<代码>数组< /COD>。HMM当我读“新C++上的动态数组循环”时,我想“多么愚蠢的问题:它只是工作!”然后我看到了这个问题,意识到“哦,当他们键入“动态数组”时,海报并不是指向量”…@默认值可能是“指向动态分配数组的指针”(有点麻烦,但会使OP将指针视为数组的错误更加明显)嗯,它工作了!我从来不知道C++是这个类型安全的,我来自C,所以它习惯于以同样的方式操纵动态和常量数组。@ MauriceRodriguez,C,数组和指针之间的差异完全相同。例如,代码> siZeof(数组)
在C语言中也返回完全不同的内容,这取决于它是
int*array=malloc(N*sizeof(int));
还是
int-array[N];
。这只是因为C使您更容易错误地忽略此差异,而不是因为此差异不存在。我不同意您应该始终在动态分配的数组上使用std::vector。=)在某些情况下,使用动态版本很重要。另外,由于我们使用的是C++11,所以std::array是一个很好的选择在使用固定大小的数组时要考虑的问题。请给我一个例子,也可以,代码< >:STD::数组< /COD>当然是好的,但是在编译时你必须知道它的大小。这可能不包括OP的情况。作为“代码> STD::矢量< /代码>的替换,我可以建议<代码> STD::DyNalds/COD>(因为C++ 1Y)如果不需要增加数组的大小。@很快
dynarray
就被C++14(“1y”)淘汰了,而且充其量只能处于实验状态,因此它可能不应该在生产中使用。您已经可以在自动分配的空数组上为
设置范围,而不需要为此添加包装器类。
int a[]{1,2,3};for(auto-it:a)std::cout 1.其他答案表明,如果动态分配的数组的大小已知,那么基于范围的循环是如何在其上完成的,因此“您不能这样做”是言过其实的。2.
std::vector
/
std::array
不能总是使用(例如,想象必须处理遗留接口)@DevNull当然可以,谢谢。我编辑了答案以澄清我的意思。@DevNull和一节关于备选方案的内容,而你只有一个指针和一个大小。没有内置的构造吗?任何拥有动态C样式数组的人都需要编写自己的包装数组结构吗?@sffc还没有,但在C++20中会有。我在下面的文章中介绍了这一点。“将声明或定义添加到命名空间std或std中嵌套的任何命名空间中是未定义的行为,下面有几个例外情况”Gross。