语义迭代器声明?

时间:2011-05-26 11:44:10

标签: c++ iterator semantics

我很抱歉这个模糊的标题,我真的不知道如何标题这个问题。

假设我有这个:

std::list<std::string> msgs;

for (std::list<std::string>::iterator it = msgs.begin(); it < msgs.end(); it++) {
    // ...
}

对我来说,这很难读懂。 std::list<std::string>::iterator几乎看起来像一个神奇的数字,特别是如果msgs的声明很远,就像在头文件中一样。 IMO它会更容易阅读,如果是这样的话会更加语义化:

std::list<std::string> msgs;

for (msgs.iterator it = msgs.begin(); it < msgs.end(); it++) {
    // ...
}

现在,这显然是非法的C ++。但我的问题是,有没有办法实现支持编写像这样的迭代器声明?

5 个答案:

答案 0 :(得分:16)

如果你提供typedef,它会让生活变得更轻松:

typedef std::list<std::string>::iterator ListIterator;
for( ListIterator it = msgs.begin(); it != msgs.end(); ++it ){}

除此之外,c ++ 0x通过提供auto关键字为您完成:

for( auto it = msgs.begin(); it != msgs.end(); ++it ){}

编辑就像5年后的日期一样,但我更新了< tp !=并使用preincrement,因为这实际上是我多年来一直在做的事情,并且更有意义对我而言,它让我想知道我是怎么写这个答案而不是用那个

答案 1 :(得分:4)

有两种实用的规范方法:

typedef std::list<int> list_t;
list_t l;

// later:
for (list_t::iterator it = l.begin(), end = l.end(); it != end; ++it) {}

C ++ 0x-only auto

std::list<int> l;

// later:
for (auto it = l.begin(), end = l.end(); it != end; ++it) {}

此外,C ++ 0x允许:

std::list<int> l;

// later:
for (decltype(l)::iterator it = l.begin(), end = l.end(); it != end; ++it)
   std::cout << *it << ", ";

我认为这是与特别提出的问题最接近的匹配(即使它不一定是最佳解决方案)。

缺点是将范围运算符(::)应用于decltype link 的能力最近才被投票到工作文件中,并且我还没有发现任何支持它的编译器(GCC 4.5.1 does not)。

答案 2 :(得分:1)

您可以使用typedef来清理它:

typedef std::list<std::string>::iterator string_iterator;

std::list<std::string> msgs;

for (string_iterator it = msgs.begin(); it != msgs.end(); it++) {
    // ...
}

答案 3 :(得分:0)

所有容器都有这些typedef,以便能够编写非常通用的代码。请考虑以下函数模板:

template<class T>
void foo(const T& container) {
    for(T::const_iterator it = T.begin(); it != T.end(); it++) {
        // do stuff
    }
}

这使您可以编写可以使用定义类型const_iterator和方法begin()end()的任何对象的代码。

在C ++ 0x中,问题通过引入auto关键字来解决:

for(auto it = container.begin(); it != container.end(); it++) {
    // do stuff
}

答案 4 :(得分:0)

规范解决方案是

std::for_each(msgs.begin(), msgs.end(), ... );

在C ++ 0x之前,写...位曾经有点困难(如果它有点复杂),但我们现在有lambda。