2015-11-11 33 views
5

這與this question類似,但不是重複的。我試圖迭代地圖並打印每個元素的值,但最後一個元素的輸出略有不同。在那個問題中,他們推薦使用map.rbegin().base(),但它不適合我。檢測迭代器是否爲std :: map的最後一個元素

這裏是我的代碼:

#include <iostream> 
#include <map> 

int main() 
{ 
    std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} }; 
    for (auto iter = charMap.begin(); iter != charMap.end(); iter++) 
    { 
     std::cout << iter->first << ":\t" << iter->second; 
     if (iter == charMap.rbegin().base()) 
      std::cout << "\t//This is the last element.\n"; 
     else 
      std::cout << "\n"; 
    } 
} 

我期望我的輸出看起來像這樣:

a: 1 
b: 2 
c: 3 
d: 4 //This is the last element. 

但是,相反,我得到這樣的輸出:

a: 1 
b: 2 
c: 3 
d: 4  

現在我意識到有更好的方法來做到這一點,但我希望這也能起作用。爲什麼我無法比較itercharMap.rbegin().base()

+0

注意,在這種情況下,它往往容易改寫循環體,使得特殊處理髮生在第一,而不是最後一個元素。 –

+1

@ChristianHackl請注意,這顯然不是這裏的情況:) – BartoszKP

+1

@BartoszKP:爲什麼不呢?開始每一行,但第一行用換行符,在循環後放置「這是最後一個元素」。 –

回答

4

base()方法將迭代器返回到逆向迭代器指向的元素之後的元素。這意味着rbegin().base()相當於end()

爲了完成你的任務,你可以這樣做:

#include <iostream> 
#include <map> 

int main() 
{ 
    std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} }; 
    for (auto iter = charMap.begin(); iter != charMap.end();) 
    { 
     std::cout << iter->first << ":\t" << iter->second; 
     if (++iter == charMap.end()) 
      std::cout << "\t//This is the last element.\n"; 
     else 
      std::cout << "\n"; 
    } 
} 
0

醜。 。 。但是。 。 。

auto iterCpy = iter; 
    if (++iterCpy == charMap.end()) 
     std::cout << "\t//This is the last element.\n"; 

使用vsoftco的答案:)

10

使用std::next<iterator>

if (std::next(iter) == charMap.end()) 
    std::cout << "\t//This is the last element.\n"; 

代替。

+0

哦,我正在使用一個單獨的迭代器,然後遞增那一個。很高興知道std :: next(); – DJMcMayhem

2

base()不返回相同的元素:

基地迭代器是指下一個元素(從std::reverse_iterator::iterator_type perspective)到reverse_iterator當前指向的元素。那是&*(rit.base() - 1) == &*rit

這按預期工作:

#include <iostream> 
#include <map> 

int main() 
{ 
    std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} }; 
    auto last = charMap.rbegin(); 
    ++last; 

    for (auto iter = charMap.begin(); iter != charMap.end(); iter++) 
    { 
     std::cout << iter->first << ":\t" << iter->second; 
     if (iter == last.base()) 
      std::cout << "\t//This is the last element.\n"; 
     else 
      std::cout << "\n"; 
    } 
} 
3

因爲std::reverse_iterator店迭代器的1補償,這樣charMap.rbegin().base() == charMap.end()。通過here的圖表說明了這一點。

您應該改用std::prevstd::next<iterator>

iter == std::prev(charMap.end()) 

std::next(iter) == charMap.end() 

無論你找到更有意義。

0

實際上,這不是指望iter確實不同於charMap.rbegin().base()

你的邏輯是正確的,唯一的問題是,charMap.rbegin().base()迭代器等於charMap.end(),但你離開你的說法,此刻iter達到charMap.end()值,所以它從來沒有在if語句來測試它裏面的機會for循環。

爲了使它工作,你可以重寫以下列方式if語句:

if (iter->first == charMap.rbegin()->first) 
    std::cout << "\t//This is the last element.\n"; 
else 
    std::cout << "\n"; 

所以你會比較地圖鍵而不是迭代器本身。

0

這是工作:

#include <iostream> 
#include <map> 

int main() 
{ 
    std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} }; 
    for (auto iter = charMap.begin(); ;) 
    { 
     std::cout << iter->first << ":\t" << iter->second;   
     if (++iter== charMap.end()){ 
      std::cout << "\t//This is the last element.\n"; break; 
     } 
     else 
      std::cout << "\n"; 
    } 

} 
相關問題