关于矢量的运算符[]

时间:2018-01-05 04:38:49

标签: c++ string vector operator-keyword

我假设可以将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());
}

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

  

错误:没有可行的重载operator []类型'vector'(又名   'vector,allocator&gt; &GT;')   string s = substrs [i];

任何人都可以解释一下吗?

4 个答案:

答案 0 :(得分:3)

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

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

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

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

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

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

答案 1 :(得分:2)

您根本不需要在此处编制索引。正如其他人所说,循环变量是向量的元素(std::string)。如果您使用auto&,则可以直接操纵vector的成员:

std::vector<string> substrs;

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

答案 2 :(得分:2)

您的代码存在的问题是&#34;现代&#34; 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());
}

答案 3 :(得分:2)

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

事实上,根本没有必要使用索引,因为基于范围的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]