在C++中增强了FOR循环

Dan*_*zer 56 c++ java for-loop

我正在从Java切换到C++,我想知道C++是否包含我在java中使用的增强for循环,例如:

int[] numbers = {1,2,3,4,5,6,7,8,9,10};
for (int item : numbers) {
  System.out.println("Count is: " + item);
}
Run Code Online (Sandbox Code Playgroud)

这是C++中可能的"快捷方式"吗?

pmr*_*pmr 73

C++ 11的确如此.它们被称为基于范围的fors.请记住,您应该将类​​型限定为引用或对const的引用.

C++ 03的解决方法是BOOST_FOR_EACHboost :: bindstd :: for_each的组合.Boost.Lambda可以提供更多精美的东西.如果你想让自己或同事感到沮丧,我推荐使用已弃用的粘合剂std::bind1ststd::bind2nd.

这是一些示例代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <boost/lambda/lambda.hpp>
#include <functional>    

int main()
{
  int i = 0;
  std::vector<int> v;
  std::generate_n(std::back_inserter(v), 10, [&]() {return i++;});

  // range-based for
  // keep it simple
  for(auto a : v)
    std::cout << a << " ";
  std::cout << std::endl;

  // lambda
  // i don't like loops
  std::for_each(v.begin(), v.end(), [](int x) { 
      std::cout << x << " ";
    });
  std::cout << std::endl;

  // hardcore
  // i know my lib
  std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << std::endl;


  // boost lambda
  // this is what google came up with
  // using for the placeholder, otherwise this looks weird
  using namespace boost::lambda;
  std::for_each(v.begin(), v.end(), std::cout << _1 << " ");
  std::cout << std::endl;

  // fold
  // i want to be a haskell programmer
  std::accumulate(v.begin(), v.end(), std::ref(std::cout), 
                  [](std::ostream& o, int i) -> std::ostream& { return o << i << " "; });

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • //嗤之以鼻的评论很有趣,+ 1 (4认同)
  • +1提及C++ 03 Boost变通方法. (3认同)

jro*_*rok 62

在C++ 11中,如果你的编译器支持它,是的.它被称为基于范围的.

std::vector<int> v;

// fill vector

for (const int& i : v) { std::cout << i << "\n"; }
Run Code Online (Sandbox Code Playgroud)

它适用于C样式数组以及具有函数begin()end()返回迭代器的任何类型.例:

class test {
    int* array;
    size_t size;
public:
    test(size_t n) : array(new int[n]), size(n)
    {
        for (int i = 0; i < n; i++) { array[i] = i; }
    }
    ~test() { delete [] array; }
    int* begin() { return array; }
    int* end() { return array + size; }
};

int main()
{
    test T(10);
    for (auto& i : T) {
        std::cout << i;   // prints 0123456789
    }
}
Run Code Online (Sandbox Code Playgroud)


Beg*_*ner 13

在C++ 03中没有这种可能性.然而,新标准(C++ 11)确实拥有它.参见示例(摘自维基百科):

int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array) {
    x *= 2;
}
Run Code Online (Sandbox Code Playgroud)

考虑使用std::vector<int>而不是普通的数组.这是C数据类型的C++类比,这使生活更轻松.


And*_*sen 12

是的,不是.

1.本地阵列:不,但您可以轻松找到大小

如果你有一个本地数组(int numbers[4] = {1, 2, 3, 4];)那么你可以做size = sizeof(numbers) / sizeof(int).

2.指向数组的指针:完全没有,你必须分别传递大小

如果你有一个指向数组(int* numbers = new int[4];)的指针,那么除非你自己跟踪它,否则你无法弄清楚它的大小.(或者如果在ac字符串的情况下它是null终止,但是你必须遍历它,这是线性运行时...)

请注意,我不相信指向数组的指针是正确的术语,实际上你只有一个指向数组第一个元素的指针,但是已经分配了多个值的空间.不确定这叫什么.也许只是一个指针?

3. STL容器:是的,你可以使用迭代器做一些循环魔术,或者只是通过获取大小来使用索引

如果你有一个vector(std::vector<int> v(3, 0);),那么你可以通过以下方式迭代它:

C++ 11:

auto it = v.begin();
for (auto it = v.begin(); it != v.end(); it++)
{
    UseElement(*it);
}
Run Code Online (Sandbox Code Playgroud)

或者显然(也是C++ 11,谢谢jrok):

for (const int& i : v) { UseElement(i); }
Run Code Online (Sandbox Code Playgroud)

C++(11之前版):

std::vector<int>::iterator it;
for (it = v.begin(); it != v.end(); it++)
{
    UseElement(*it);
}
Run Code Online (Sandbox Code Playgroud)

或使用指数:

for (int i = 0; i < v.size(); i++)
{
    UseElement(v[i]);
}
Run Code Online (Sandbox Code Playgroud)

此外,您可以使用std算法的for_each(#include <algorithm>)来使用带有STL容器的函数指针或仿函数,如下所示:

void foo(int i)
{
    std::cout << i;
}

{
    std::for_each(myvector.begin(), myvector.end(), foo);
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*nta 6

在旧标准C++ 03(来自2003年)中,该语言没有内置支持这种for循环.你可以在Boost中使用一些技术,但是这个小便利功能不值得包括一个全新的库.

在新标准C++ 11(去年夏天发布)中,这是可能的; 语法如下所示:

MyType array[] = { ... }
for (MyType& x : array) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,我正在使用MyType& x,而不是MyType x.在Java中,一切都是参考.在C++中,引用必须是显式的,并且您使用它来声明它们&.如果不使用引用,for循环将复制数组的每个元素x(这可能很昂贵).

但是,大多数编译器还没有完全支持C++ 11.我认为微软的Visual C++支持这个功能,但我不确定.


cel*_*chk 6

其他人已经提到过这种循环风格是在C++ 11中添加的.但是C++ 11甚至更好:

for (auto const& item: numbers)
{
  std::cout << "Count is: " << item << '\n';
}
Run Code Online (Sandbox Code Playgroud)

这样,如果您稍后将numbersfrom 的元素类型更改intlong,或者甚至bigint更改为您自己编写的某个类,则根本不需要更改for循环.