问题描述
|
很抱歉,标题很模糊,我真的不知道如何为这个问题加上标题。
假设我有这个:
std::list<std::string> msgs;
for (std::list<std::string>::iterator it = msgs.begin(); it < msgs.end(); it++) {
// ...
}
对我来说,这很难读。 std::list<std::string>::iterator
几乎像是一个魔术数字,尤其是如果if2ѭ的声明距离很远,例如在头文件中。 IMO,如果是这样的话,将更容易阅读并且语义更多:
std::list<std::string> msgs;
for (msgs.iterator it = msgs.begin(); it < msgs.end(); it++) {
// ...
}
现在,这显然是非法的C ++。但是我的问题是,有没有一种方法可以实现一些支持编写这样的迭代器声明的方法?
解决方法
如果提供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!=
并使用了预增量功能,因为这实际上是我多年来所做的事情,并且对我来说更有意义,以至于使我不知道我曾经写过什么这个答案不使用那个
,有两种实用的规范方法:
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的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
链接的功能只是最近才在工作文件中投票通过的,我还不知道任何支持它的编译器(GCC 4.5.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++) {
// ...
}
,所有容器都具有这15个字符,以允许编写非常通用的代码。考虑以下功能模板:
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
}
,规范的解决方案是
std::for_each(msgs.begin(),msgs.end(),... );
在C ++ 0x之前,写...
位曾经有点困难(如果有些复杂的话),但是现在有了lambda。