我假设可以使用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];
谁能解释一下?
您使用错误的类型进行索引。您正在使用字符串进行索引。
for(auto i: substrs) { ... }
auto
有一个std::string
类型,而不是算术类型。您不能按字符串索引矢量。
如果需要索引,请尝试使用for (size_t i = 0; i < substrs.size(); ++i) { ... }
,或使用C ++的自动范围。
编辑正如Code-Apprentice所述,您可能想要的是:
for (auto& str: substrs) { ... }
你根本不需要在这里索引。正如其他人所说,循环变量是向量的元素(std::string
)。如果你使用auto&
,那么你可以直接操纵vector
的成员:
std::vector<string> substrs;
for(auto& s : substrs){
s.erase(remove(s.begin(), s.end(), ' '), s.end());
}
您的代码的问题是“现代”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());
}
当使用基于范围的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]