关于 vector 的 operator[]
About operator[] of vector
我假设可以将 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());
}
由于以下错误,上述代码段无法编译:
error: no viable overloaded operator[] for type 'vector' (aka
'vector, allocator > >')
string s = substrs[i];
谁能解释一下?
您正在使用错误的类型进行索引。您正在使用字符串进行索引。
for(auto i: substrs) { ... }
auto
有一个 std::string
类型,不是算术类型。您不能按字符串索引向量。
如果需要索引,请尝试使用 for (size_t i = 0; i < substrs.size(); ++i) { ... }
,或者使用 C++ 的自动范围。
编辑 如代码学徒所述,您可能需要的是:
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());
}
您的代码的问题是 "modern" 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]
我假设可以将 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());
}
由于以下错误,上述代码段无法编译:
error: no viable overloaded operator[] for type 'vector' (aka 'vector, allocator > >') string s = substrs[i];
谁能解释一下?
您正在使用错误的类型进行索引。您正在使用字符串进行索引。
for(auto i: substrs) { ... }
auto
有一个 std::string
类型,不是算术类型。您不能按字符串索引向量。
如果需要索引,请尝试使用 for (size_t i = 0; i < substrs.size(); ++i) { ... }
,或者使用 C++ 的自动范围。
编辑 如代码学徒所述,您可能需要的是:
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());
}
您的代码的问题是 "modern" 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]