簡體   English   中英

我應該通過迭代器還是訪問運算符迭代向量?

[英]Should I iterate a vector by iterator or by access operator?

我有一個聲明為的向量

std::vector<int> MyVector;
MyVector.push_back(5);
MyVector.push_back(6);
MyVector.push_back(7);

我應該如何在for循環中使用它?

通過迭代器迭代它?

for (std::vector<int>::iterator it=MyVector.begin(); it!=MyVector.end(); ++it)
{
    std::cout << "Vector element (*it): " << *it << std::endl;
}

或者通過它的訪問迭代器?

for (std::vector<int>::size_type i=0; i<MyVector.size(); i++)
{
    std::cout << "Vector element  (i) : " << MyVector.at(i) << std::endl;
}

在我在互聯網上找到的例子中都使用了它們。 在所有條件下,其中一個優於另一個嗎? 如果沒有,我什么時候應該更喜歡其中一個呢?

第一種格式是更通用的格式,用於迭代標准庫容器,因此它更常見,更直觀。 如果你需要更改容器,那么這個迭代代碼仍然沒有受到影響。它將適用於每個標准庫容器類型,因此它為您提供了更多通用代碼。

在第二種格式中, std::vector::at()每次迭代時都會檢查邊界,因此它可能對性能有點不利 由於沒有涉及邊界檢查,因此第一種格式中不存在此開銷。請注意,使用operator[]的情況也是如此。
請注意,性能滯后不會像您注意到的那樣多,除非您正在操作大量數據。

使用std::vector's [] operator可能更快,因為std::vector::at() for循環中使用std::vector::at()檢查向量的大小兩次(在for循環和std :: vector :: at()的邊界內檢查)。

第一種方法可以在其他容器中使用,因此在更改容器類型時可以幫助您。

如果使用C ++ 11,請使用基於范圍的循環。

首先,如果你有C ++ 11,請使用基於范圍的:

for (auto i : MyVector)
{
    std::cout << i;
}

或C ++ 03中的BOOST_FOREACH

BOOST_FOREACH(int& i, MyVector)
{
  std::cout << i;
}

或者std::copy

std::copy(MyVector.begin(),
          MyVector.end(), 
          std::ostream_iterator<int>(std::cout, "\n"));

至於手頭的問題, at()檢查索引是否在邊界內,如果不是則拋出異常。 所以,除非你需要額外的檢查,否則不要使用它。 你擁有它的第一種方式是標准的並且效果很好。 有些人很迂腐,甚至寫得像:

for (std::vector<int>::iterator it=MyVector.begin(), end = MyVector.end(); it!= end; ++it)
{
    std::cout << "Vector element (*it): " << *it << std::endl;
}

在上面我緩存了end迭代器而不是調用end()每個循環。 不知道這是否真的會帶來性能差異,我不知道。

沒有“一個優於另一個”(除了你幾乎從不想使用at() - at()只適用at()你可以真正從錯誤中恢復的東西)。 迭代器與索引的使用主要是樣式和您傳遞的消息之一。 更慣用的C ++做事方式是迭代器,但來自其他背景的人(例如,數學家)會發現索引更具慣用性。

有一些真正的區別:

  • 迭代器習語可以與其他類型的容器一起使用。 如果您真的有可能使用其他容器,這可能是相關的。

  • 索引習慣用法可以為幾個不同的容器使用單個索引。 如果您正在迭代幾個具有相同大小的vector ,則使用索引慣用法會更清楚地表明您正在訪問每個vector的相同元素。 (同樣,這似乎最常出現在數學應用中。)

  • 最后,每當你真正進行隨機訪問或以任何方式計算元素時,使用索引可能更直觀。 (在這種情況下,您可能希望在int進行計算,僅在最后時刻轉換為size_t 。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM