【问题标题】:STL iterator loopsSTL 迭代器循环
【发布时间】:2012-07-20 03:27:54
【问题描述】:

我写了这段代码:

#define VECTOR_LOOP_V(X) for (vector<typeof(X)>::iterator it = X.begin(); it != X.end(); it++)

为了更快地为向量编写 for 循环,但由于某种原因它不起作用,当我尝试编译它时,它给了我非常非常长的错误消息。

 test.cpp: In function ‘int main(int, char**)’:
test.cpp:20:5: error: conversion from ‘std::vector<std::basic_string<char> >::iterator {aka __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >}’ to non-scalar type ‘std::v

等等。

【问题讨论】:

  • 相信我,对于 C++,这是一个非常非常短的错误消息。
  • 你应该写完整的错误信息,而不是随便剪到某个地方。我敢打赌,删掉的第一个字符会说类似std::vector&lt; std::vector&lt; std::basic_string... 的内容,这应该会给你一个关于副本结构左侧是什么的提示......
  • C++11 对你不可用,我猜?基于范围的for 循环是新的热点。
  • 如果您还没有基于范围的for,请尝试 Boost FOREACH。

标签: c++ stl vector std


【解决方案1】:
#define VECTOR_LOOP_V(X) \
     for (vector<typeof(X)>::iterator it = X.begin(); \
          it != X.end(); it++)

您打算如何使用宏?看起来X 是容器,在这种情况下,for 的第一部分应该类似于typeof(X)::iterator (甚至不知道这是否合法,因为typeof 不是标准的并且从来没有使用)。

或者,您可以只使用 boost::foreach ,它提供了一个类似但更丰富的宏,其优点是它在许多方面更安全。例如,如果参数是一个按值返回的函数调用,您的宏将非常糟糕:

std::vector<int> f();
VECTOR_LOOP_V( f() ) {
   std::cout << *it << "\n";
}

问题与您多次评估参数的几乎所有宏一样,在您的情况下,it 将是一个迭代器到一个 std::vector&lt;int&gt; 和终止条件将尝试将它与来自不同 @ 的迭代器进行比较987654330@.

【讨论】:

  • 它对 C++11 中的 decltype 有效,但尚未得到适当支持:stackoverflow.com/a/5525623/168175
  • @Flexo,这个答案已经有一年多了,G++ 4.7 处理得很好。
  • @JonathanWakely - 真的吗?前几天在(类似的)场景中尝试 4.7 时,我无法让它工作。
  • 也许你忘了-std=c++11
【解决方案2】:

它不起作用,因为 typeof(X) 产生 std::vector 类型,因此宏扩展为:

for (vector<std::vector<...> >::iterator it = X.begin(); it != X.end(); it++)

另外,如果X 是常量,您的宏将会失败,在这种情况下应该使用const_iterator。还有很多其他问题,但无论如何,您尝试做的事情是这样的:

#define VECTOR_LOOP_V(X) \
    for (typeof(X.begin()) it = X.begin(), eit = X.end(); it != eit; ++it)

.. 下面是一些用法示例:

#include <vector>
#include <iostream>

#define VECTOR_LOOP_V(X) \
    for (typeof(X.begin()) it = X.begin(), eit = X.end(); it != eit; ++it)

int main()
{
    std::vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(5);
    VECTOR_LOOP_V(v) {
        std::cout << *it << std::endl;
    }
}

但请注意,typeof 不是标准 C++(请参阅this Q/A)。

总而言之,你最好使用BOOST_FOREACH(或者至少看看它是如何在那里实现的)或C++11 range-based for循环。

P.S.:不要使用 STL 缩写,除非你真的是指 STL 而不是 C++ Standard Library(你可以将其称为 stdlib)。

【讨论】:

  • 谢谢!我会研究基于范围的循环,你的信息真的很有用!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-24
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多