如何在C++ 11的迭代器中获得有关auto标识符的更多细节

1 c++ c++11

 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;
     }
}
Run Code Online (Sandbox Code Playgroud)

在第一个循环中,我可以确定类型的迭代器是vector<string>::iterator.我想知道什么是类型it2(我已经尝试过使用vector<string>::const).我怎样才能获得关于哪种类型auto相同的更多细节.

Bar*_*rry 5

it是一个迭代器vector<string>.这意味着it"指向"a string.因此,当你写作,it->begin()并且it->end(),你正在迭代string,这将使it2类型std::string::iterator.正如YakkWakely先生的评论中明确指出的那样,这种类型并不重要.它只是"指向"某种东西的类型char,我们可以通过它来迭代我们的东西string.这是其中一个主要卖点auto- 如果类型的名称无关紧要,请不要使用它来混淆代码.

请注意,由于您在代码中实际上从未需要迭代器,因此可以使用基于范围的for循环来避免它们:

for (auto& str : s) {
    for (auto& chr: str) {
        chr = toupper(chr);
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果你需要知道某些东西的确切类型,我会推荐以下hack.创建一个类型但从未定义的类模板:

template <typename > struct TD; // for Type Description
Run Code Online (Sandbox Code Playgroud)

然后把它贴在某个地方:

for (auto it2 = ... ) {
    TD<decltype(it2)> t;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这会给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;
                                  ^
Run Code Online (Sandbox Code Playgroud)

请注意,编译错误中包含完整类型it2.

  • 另请注意,`string :: iterator`作为一个类型意味着除了`string.begin()`的结果.从某种意义上说,`string :: iterator`是一个类型*,没有信息*超出产生它的表达式. (2认同)