关于矢量的运算符[]

问题描述 投票:0回答:4

我假设可以使用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 >>')string s = substrs [i];

谁能解释一下?

c++ string vector operator-keyword
4个回答
3
投票

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

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

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

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

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

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

2
投票

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

std::vector<string> substrs;

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

2
投票

您的代码的问题是“现代”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());
}

2
投票

当使用基于范围的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]
© www.soinside.com 2019 - 2024. All rights reserved.