函数advance()
的定义是:
template<class InIt, class Dist>
void advance(
InIt& it,
Dist n
);
当我在我的代码中使用此函数时:
string strArr[10];
strArr[0] = string("dd");
strArr[1] = string("gg");
strArr[2] = string("tt");
const vector<string> vecStr(strArr, strArr+6);
advance(vecStr.begin(), 2);
cout<<*(vecStr.begin())<<endl; // the output is dd
您知道函数advance()
中的第一个参数是引用,因此在advance(vecStr.begin(), 2);
之后,verStr.begin()
应指向vecStr[2]
。
但是从输出中我们发现vecStr.begin()
指向str[0]
。
我想知道吗?
答案 0 :(得分:2)
advance(vecStr.begin(), 2);
cout<<*(vecStr.begin())<<endl; // the output is dd
您正在使用两个不同的迭代器,其中一个使用advance
,另一个使用打印。
要使代码正常工作,请在同一个迭代器上使用advance
和cout
auto iter = vecStr.begin();
advance(iter , 2);
cout << *iter << endl;
只是在原始代码中注释,advance(vecStr.begin(), 2);
实际上不会编译,至少在使用严格的编译器设置时。 vecStr.begin()
返回一个临时对象,该对象无法绑定到std::advance
的第一个参数,这是一个l值引用。
此外,std::vector::begin()
在逻辑上返回向量内实际开始迭代器的副本,而不是对它的引用。这意味着无论你对返回的迭代器做什么都不会反映到向量内的begin迭代器。我在这里谈的是迭代器,而不是它们指向的元素。
答案 1 :(得分:1)
std::advance
不会更改std::vector
下的迭代器,也不会改变临时迭代器
// this will advance on a temporary iterator returned from vecStr.begin()
// it shouldn't compile as C++ doesn't allow bind reference to temporary object
advance(vecStr.begin(), 2);
您可以编译代码的原因是您使用的是Visual Sutdio扩展C4239,有时也称为 evil 扩展名。
你应该这样做:
auto biter = vecStr.begin(); // biter points to begin of vecStr
std::advance(biter, 2); // advance biter by 2 position
std::cout<< *biter << std::endl;
答案 2 :(得分:0)
vector::begin()
是一个返回迭代器的函数。你不能通过修改它返回的迭代器来改变begin()
返回的内容 - 你只能通过修改向量内容来改变返回的内容。
请改为尝试:
auto it = vecStr.begin();
advance(it, 2);
cout<<*(it)<<endl;
答案 3 :(得分:0)
您的代码does not compile under a standards conforming compiler。我猜你正在使用Visual Studio,你的警告级别还不足以告诉你有关临时工具的参考资料。
vector::begin()
不会将引用返回给迭代器。它按值返回迭代器 ;它返回一个临时的。 std::advance
的第一个参数是非const引用。在标准C ++中,不允许绑定到临时参数。所以你的代码无法编译。
但是在VS上,允许这样做,这不会做你想要的,因为你推进了一个临时对象,而不是vector
中实际“存储”的东西。毕竟,vector
可能实际上并不存储这些东西;它们可以从任意数据生成。因此,您不能简单地修改vector
中的迭代器,因为vector
可能中没有迭代器。