【问题标题】:About operator[] of vector关于vector的operator[]
【发布时间】:2018-06-14 21:23:23
【问题描述】:

我假设可以将operator[] 用于任何vector,而不管它包含的数据类型如何。我编写了这个算法来从字符串中删除空格,其中每个字符串都使用operator[]从字符串向量中索引。

std::vector<string> substrs;
//after reading strings into the vector
//by means of user input
for(auto i : substrs){
    string s = substrs[i];
    s.erase(remove(s.begin(), s.end(), ' '), s.end());
}

由于以下错误,上述代码段无法编译:

错误:对于“向量”类型(又名 '向量,分配器> >') 字符串 s = substrs[i];

谁能解释一下?

【问题讨论】:

  • 您正在使用基于范围的 for 循环。您在 i 中拥有的是向量中的字符串。

标签: c++ string vector operator-keyword


【解决方案1】:

您使用了错误的类型进行索引。您正在使用字符串进行索引。

for(auto i: substrs) {  ... }

auto 有一个 std::string 类型,而不是算术类型。您不能按字符串索引向量。

如果您需要索引,请尝试使用 for (size_t i = 0; i &lt; substrs.size(); ++i) { ... },或使用 C++ 的自动范围。

编辑 正如 Code-Apprentice 所指出的,您可能想要的是:

for (auto& str: substrs) { ... }

【讨论】:

  • 请注意,对于 OP 中的用例,for (auto&amp; s : substrs) 可能是最合适的循环。
  • 感谢您的所有 cmets。
【解决方案2】:

您根本不需要在这里建立索引。正如其他人所说,循环变量是向量的元素(std::string)。如果你使用auto&amp;,那么你可以直接操作vector的成员:

std::vector<string> substrs;

for(auto& s : substrs){
    s.erase(remove(s.begin(), s.end(), ' '), s.end());
}

【讨论】:

    【解决方案3】:

    您的代码的问题是“现代” for 循环遍历 std::vector 的值(它适用于任何集合)。它不会遍历向量元素的索引。

    不过,你必须小心。 for(auto s:substr) 将创建(并放入 s)每个字符串的副本。如果修改此副本,则不会修改集合内的实际字符串。您需要的是创建对向量内每个字符串的引用。看这个例子:

    #include <iostream>
    #include <vector>
    #include <string>
    
    int main()
    {
        std::vector<std::string> a { "a", "b"};
    
        for (auto s: a) {
            s = "x";
        } 
    
        for (auto s: a) {
            std::cout << "element: " << s << std::endl;
        } 
    
        for (auto &s: a) {
            s = "x";
        } 
    
        for (auto s: a) {
            std::cout << "element: " << s << std::endl;
        } 
    
        return 0;
    }
    

    将输出:

    element: a
    element: b
    element: x
    element: x
    

    所以你需要解决的问题是:

    for(auto &s: substrs){
       s.erase(remove(s.begin(), s.end(), ' '), s.end());
    }
    

    【讨论】:

      【解决方案4】:

      当使用基于范围的for 时,控制变量采用您正在迭代的集合中项目的类型,而不是(您似乎认为的)集合中的数字索引。

      事实上,根本不需要使用索引,因为基于范围的for 让您直接 访问集合中的每个项目 - 只需按照您认为合适的方式对其进行修改。

      下面的完整程序展示了如何做到这一点:

      #include <iostream>
      #include <vector>
      #include <string>
      #include <algorithm>
      
      int main() {
          // Create a test vector.
      
          std::vector<std::string> stringVec;
          stringVec.push_back("Hello, my name is pax");
          stringVec.push_back("My hovercraft is full of eels");
      
          // Output the initial items (with spaces).
      
          for (const auto &str: stringVec)
              std::cout << '[' << str << ']' << std::endl;
      
          // Remove spaces from each item.
      
          for (auto &str: stringVec)
              str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
      
          // Output the final items (no spaces any more).
      
          for (const auto &str: stringVec)
              std::cout << '[' << str << ']' << std::endl;
      }
      

      输出如预期:

      [Hello, my name is pax]
      [My hovercraft is full of eels]
      [Hello,mynameispax]
      [Myhovercraftisfullofeels]
      

      【讨论】:

        猜你喜欢
        • 2012-06-15
        • 2016-08-30
        • 2015-06-13
        • 2012-01-03
        • 1970-01-01
        • 2022-11-21
        • 1970-01-01
        • 2021-10-11
        • 2021-10-09
        相关资源
        最近更新 更多