如何创建没有类型名称的迭代器?

How to create iterator without type names?

例如,我有一个 std::map<int, string> _m;,我想遍历它。 所以我必须写这样的东西:std::map<int, string>::iterator it = _m.begin()

问题是是否可以在不使用类型名称的情况下创建迭代器。编译器在创建迭代器的时候就知道 _m 的类型,那我为什么要自己写这些类型呢?

更新 我忘了说我必须使用旧的 C++ 标准。

您在 auto 关键字之后:

auto it = _m.begin();

Compiler knows the type of _m at the moment of creation of iterator, so why do I need to write those types myself?

是的,这就是导致引入 auto 确切 逻辑。

如果你不能使用 C++11,你就会陷入 typedef 之类的困境。引入新标准的全部原因 auto 是因为您面临的确切问题 - 一直手动写出长类型名称很尴尬。

typedef std::map<int, string>::iterator map_itr;

map_itr it = _m.begin();

实际上可以使用模板函数:

template <typename ITERATORTYPE> void myfunc(ITERATORTYPE it) {
    //.. do whatever you want with your it
}

然后调用模板:

myfunc(_m.begin());

最好的通用方法是使用 C++11 的 auto 关键字作为类型。在以后的版本中,使用没有任何类型信息的基于范围的循环可以做得更好。

for (it : _m) {
    /* ... */
}

如果您坚持使用旧版本,缩短类型名称的唯一方法是创建模板。不过,这可能比写名字更复杂。类似的东西:

template <typename T> 
void do_foo(T it, T end) {
    for (; it < end; ++it) {
        /* ... */
    }
 }

 do_foo(_m.begin(), _m.end());

如果包装算法不是您的算法,您也可以使用 typedef 来缩短它,但您仍然需要输入一次名称。

如果您坚持使用 C++03,如果您 确实 需要它,则无法在不拼写的情况下引用该类型。你能做的最好的事情就是引入一个 typedef (或更多)这样你只需要输入一次 long 类型:

typedef std::map<int, string> TypeOfM;
typedef TypeOfM::iterator MIterator;
TypeOfM _m;

然而,当您使用标准库算法时,您不必明确命名迭代器:

std::for_each(_m.begin(), _m.end(), /* a functor */);

如果 Boost 是一个选项,而您真的只想迭代,您也可以使用 Boost.Foreach。不幸的是,这仍然需要一个 typedef,因为 mapvalue_type 是一对,因此包含一个 ,,这会使预处理器出错:

typedef std::pair<const int, string> Pair;
BOOST_FOREACH(const Pair &p, _m)
{
  // Do whatever you need
}

由于您正在尝试对其进行迭代,因此您可以尝试 <algorithm> 之一,例如 std::for_each 并传递函数

既然你指定你被及时锁定到 C++98,那么你所拥有的最好的东西就是背后的黑魔法 BOOST_AUTO。

#include <boost/typeof/typeof.hpp>
#include <map>
#include <string>

int main()
{
     std::map<int, std::string> m;
     BOOST_AUTO(it, m.begin());
}

BOOST_FOREACH 是作为处理循环的类似事物而创建的,无需指定迭代器类型。

#include <boost/foreach.hpp>
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v;
    // populate v...

    BOOST_FOREACH(int const &i, v)
    {
        std::cout << i << "\n";
    }
}