C++ 在C+中命名和使用迭代器的常规惯例是什么+;?

C++ 在C+中命名和使用迭代器的常规惯例是什么+;?,c++,naming-conventions,iterator,C++,Naming Conventions,Iterator,我觉得我命名和使用迭代器的方式很不专业。我的意思是,我“觉得”我应该叫他们别的名字,但我总是根据“it_uuu”前缀给他们命名,过了一段时间,在一个长函数中,这些名字开始看起来很像 此外,我总是想知道我是不是在用一种“奇怪”的方式做事,而这种方式正是我所学到的,只是因为我不太懂。例如,如果我遍历一个映射以显示其所有键/值对,我会这样做: map<int, int>::const_iterator it = layout.begin(); for (; it != layout.end

我觉得我命名和使用迭代器的方式很不专业。我的意思是,我“觉得”我应该叫他们别的名字,但我总是根据“it_uuu”前缀给他们命名,过了一段时间,在一个长函数中,这些名字开始看起来很像

此外,我总是想知道我是不是在用一种“奇怪”的方式做事,而这种方式正是我所学到的,只是因为我不太懂。例如,如果我遍历一个映射以显示其所有键/值对,我会这样做:

map<int, int>::const_iterator it = layout.begin(); for (; it != layout.end(); ++it) { cout << it->first << ":\t" << it->second << "\n"; } map::const_迭代器it=layout.begin(); for(;it!=layout.end();++it) {
首先,这个名字对我来说是最不重要的,只要它清楚并且选择得当

这就陷入了变量命名的无休止的争论中

  • m_u成员
  • 成员的尾随下划线
  • 等等

我尽量在
for
循环中声明迭代器,以便使迭代器标识符的范围最小化

首先,I
typedef
将“长”类型名称改为“短”和可重复使用的名称:

typedef std::map< int, int > IntMap;
typedef IntMap::const_iterator IntMapConstIter;
我是这样做的

for (map<int, int>::const_iterator it = layout.begin();
     it != layout.end(); ++it)
{
    cout << it->first << ":\t" << it->second << "\n";
}
for(map::const_iterator it=layout.begin();
it!=layout.end();++it)
{

cout first我非常确定,在这个问题上,没有任何约定可以超越样式。我相信迭代器命名最重要的部分是在第二部分(考虑到您决定添加前缀,应该是“it”或“iter_2;”或其他任何内容)。像对待任何其他变量一样,仔细选择第二部分,你会没事的。

我建议使用迭代器,你(大部分)忘记迭代器,这是完全不合理的吗?

我没有见过一个规范循环

创建
迭代器
的成本指定为
O(1)
(wrt容器的大小),但它可能需要成本,特别是在激活特定调试选项时

因此,在循环的每次迭代中调用
end
,是一种浪费

因此,为
循环编写
的标准方法是在第一条语句中计算
it
end

typedef std::map<int,int> LayoutType;

for (LayoutType::const_iterator it = layout.begin(), end = layout.end();
     it != end; ++it)
{
  // ...
}
typedef std::map LayoutType;
对于(LayoutType::const_迭代器it=layout.begin(),end=layout.end();
它!=结束;++它)
{
// ...
}
我通常用typedef定义我的容器,但老实说,用typedef定义迭代器没有多大意义,迭代器已经在容器中可用了,引入太多同义词也没有帮助

另外,这可能是我个人的一个怪癖,但我更喜欢在介绍typedef时说明函数而不是类型。类型可能会在以后的重构中发生变化,函数不会发生变化(至少,如果它发生变化,它将完全不同,因此需要完全重写)


例如,如果您突然选择:
typedef std::无序地图布局类型
?它仍然符合您的需要,并且您可能无需重新编写它(前提是您使用了typedef)。

我甚至没有考虑过这一点,我担心的一件事是范围。您如何处理难以置信的长时间倾向于结果的“for”语句?我能想到的最好方法是为数据类型生成一个typedef来缩短它。我不喜欢仅仅为了缩写而使用typedef,它增加了其他简单代码的复杂性,但没有多少好处。C++0x最好的部分之一是
auto it=layout.begin()
@Adam:我也是这么想的。因此,为了减少冗余、易于更改容器类型和可读性,我使用了上面提到的IntMap之类的TypeDef,但是我会使用IntMap::const_迭代器,因为我看不到IntMapConsitter更容易理解,它只是更小,丢失了与IntMap的关系信息,一个d不抽象任何内容,因为它以后不需要重命名和重新检查客户端使用情况就不能更改为任何其他类型的迭代器。@ArunSaha:1回答:
auto
通过类型推断区分
iterator
const\u迭代器
,如果容器是
const
它将是
const\u迭代器
否则一个`迭代器.2注释:第二个typedef对代码的影响大于它对代码的帮助,第一个typedef应该有一个函数名,确切的类型是一个可能会演变的实现细节。太好了!我以前看到ArunSaha给出了同样的答案,而这段时间我甚至没有想过打破“for”的定义“循环成几行来处理长度。谢谢!不客气,有时候最简单的解决方案是最难注意到的。一点也不,我只是还没有使用Boost-尽管我知道它提供的所有酷东西。我没有使用Boost的foreach(使用了特定于项目的实现)。不过,当你在迭代过程中插入或删除、同时跟踪多个迭代器等时,在迭代器级别思考是很好的。我不认为boost foreach在这些情况下提供了任何东西…?@Tony:没有,但在迭代过程中修改容器的底层结构…这很难做到正确。我非常喜欢对于任务,我更喜欢使用
算法
,或者使用一个备用的临时数据结构,我将在循环结束时与当前数据结构进行切换。@Matthieu:棘手-是;可行的情况下,有好的替代方法。干杯。几乎我所有的循环变量都称为
循环
(除非有双重嵌套)@Martin:我的迭代器通常是
it
end
…但是现在一直使用
BOOST\u-FOREACH
,我不经常把它们带出来。我会尝试用一个算法替换一个循环。而不是一个fan-BOOST\u-FOREACH,因为它的名字都是大写的(使代码看起来很难看).1对于许多优点,尽管我认为整个端部预计算问题被夸大了-只有极端情况或糟糕的设计才会导致慢端();-)。
typedef std::map<int,int> LayoutType;

for (LayoutType::const_iterator it = layout.begin(), end = layout.end();
     it != end; ++it)
{
  // ...
}