C++迭代程序,有什么作用!=真的很刻薄

C++ Iterators, what does != really mean?

本文关键字:真的 作用 程序 迭代 什么 C++      更新时间:2023-10-16

我刚开始研究这个问题,遇到了这样的例子

double value1, value2;
std::istream_iterator<double> eos;              // end-of-stream iterator
std::istream_iterator<double> iit (std::cin);   // stdin iterator
if (iit!=eos) value1=*iit;
++iit;

所以我想,就像任何有广泛OO背景但不是最近的C的人一样,我认为WTF!人们会期望看到类似的东西

while (iit.next()) ... iit.value()

但我可以理解,对于一个C程序员来说,做指针运算感觉像是一种自然的迭代器(!!)。

因此,像*这样的运算符可以被推翻,做完全不同的事情。但是这是怎么回事操作员做什么?文档表示,这一条并没有以某种奇怪的方式被覆盖。那么它怎么可能工作呢?

我可以从C的角度看到,这就像是在字符串中寻找那个可爱的尾随null。但在这里,我不希望有一些神奇的双值被用作令牌。它用NaN还是什么的?

假设您有:

int arr[10];

在C中,要迭代数组,最常用的方法是:

for ( int i = 0; i < 10; ++i )
{
   doSomething(arr[i]);
}

你也可以在C++中做到这一点。然而,C++编程习惯用法已经发展到更自然的地方:

int* end = arr + 10;
for ( int* iter = arr; iter != end; ++iter )
{
   doSomething(*iter);
}

您可以使用该习惯用法来迭代容器,如std::vectorstd::setstd::map等。

std::map<int, int> aMap = { ... };
std::map<int, int>::iterator end = aMap.end();
for ( std::map<int, int>::iterator iter = aMap.begin(); iter != end; ++iter )
{
   int key = iter->first;
   int value = iter->second;
   // Use key and value
}

标准算法库中的大多数(如果不是全部的话)函数都是为使用迭代器s的概念而设计的。

如果您可以访问C++11编译器,通过使用新的范围-for循环、auto关键字来推导变量类型以及std::begin()std::end(),可以进一步简化上述代码块。

对于阵列:

for ( auto val : arr )
{
   doSomething(val);
}

auto end = std::end(arr);
for ( auto iter = std::begin(arr); iter != std::end; ++iter )
{
   doSomething(*iter);
}

对于std::map:

for ( auto& item : aMap )
{
   int key = item.first;
   int value = item.second;
   // Use key and value
}

auto end = std::end(aMap);
for ( auto iter = std::begin(aMap); iter != end; ++iter )
{
   int key = iter->first;
   int value = iter->second;
   // Use key and value
}

auto end = aMap.end();
for ( auto iter = aMap.begin(); iter != end; ++iter )
{
   int key = iter->first;
   int value = iter->second;
   // Use key and value
}

对于您的具体问题,std::istream_iterator<double>的使用方式非常相似。它可以用于从std::istream读取数据,并且数据可以用于各种算法。它的两个重要成员函数是operator*operator->过载。当调用这些函数时,迭代器从其关联的std::istream中读取一个类型为double的对象并返回数据。因此,您可以在for循环中使用它作为:

std::istream_iterator<double> iter(std::cin); 
std::istream_iterator<double> end;
for ( ; iter != end; ++iter )
{
   double val = *iter;
   std::cout << "Got " << val << std::endl;
}