2015-09-28 60 views
1
void test() 
{ 
     vector <string> s={"hello world"}; 
     for(vector<string>::iterator it=s.begin();it!=s.end()&&!it->empty();it++) 
     { 
      for(auto it2=it->begin();it2!=it->end();it2++)//I don't konw type of it2 
      { 
       *it2=toupper(*it2); 
      } 
     cout<<*it<<endl; 
    } 
} 

迭代器獲得更詳細的關於汽車的標識。在第一圈,我可以肯定類型的這個迭代是vector<string>::iterator。我想知道什麼是it2的類型(我已經嘗試過使用vector<string>::const)。我怎樣才能獲得更多關於auto的哪個類型相同的細節。如何在C++ 11

+4

請問,您爲什麼需要知道? – Bathsheba

+3

'*(it)'的類型是'std :: string&',因此請檢查[std :: string :: begin()]的類型(http://en.cppreference.com/w/cpp/string/basic_string/begin)(no'const') - >它是'std :: string :: iterator' – BeyelerStudios

+0

我在閱讀第三章中的「C++總理」並做了一些書的練習。該問題要求使用迭代器來實現。我首先使用auto,但對迭代器的具體類型感到好奇。 – HugoZou

回答

5

it是進入vector<string>的迭代器。這意味着it「指向」一個string。因此,當您編寫it->begin()it->end()時,您正在迭代string,這將使it2的類型爲std::string::iterator。正如在YakkMr. Wakely的評論中巧妙地指出的那樣,這種類型並不重要,。它只是一種「指向」char的東西,我們可以通過它迭代我們的string。這是auto的主要賣點之一 - 如果類型的名稱無關緊要,請不要混淆您的代碼。

注意,因爲你從來沒有真正需要的迭代器在你的代碼,你可以簡單地避免它們與一系列爲基礎的循環:

for (auto& str : s) { 
    for (auto& chr: str) { 
     chr = toupper(chr); 
    } 
} 

或者,如果你需要知道確切類型的東西,我會推薦以下hack。做一個類模板,需要一個類型,但從未定義:

template <typename > struct TD; // for Type Description 

然後就是堅持在某處:

for (auto it2 = ...) { 
    TD<decltype(it2)> t; 
    // ... 
} 

這將提供以下錯誤用gcc 5.2:

main.cpp:16:34: error: aggregate 'TD<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> > > t' has incomplete type and cannot be defined 
       TD<decltype(it2)> t; 
           ^

請注意,編譯錯誤中包含it2的完整類型。

+2

另請注意,'string :: iterator'作爲一個類型意味着除了'string.begin()'的結果之外別無他法。從某種意義上說,'string :: iterator'是一個沒有信息的*類型,超越了產生它的表達式。 – Yakk

+1

@Yakk的確如此!一個非常好的觀點,那些對「自動」感到「害怕」的人會忘記!說'string :: iterator it2 = it-> begin()'沒有比'auto it2 = it-> begin()'更有用,他們都會說「給我一個由'it-> begin返回的類型的變量()'」 –