关于STL的进展

时间:2013-08-10 04:08:25

标签: c++ stl

函数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]

我想知道吗?

4 个答案:

答案 0 :(得分:2)

advance(vecStr.begin(), 2);
cout<<*(vecStr.begin())<<endl; // the output is dd

您正在使用两个不同的迭代器,其中一个使用advance,另一个使用打印。

要使代码正常工作,请在同一个迭代器上使用advancecout

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可能中没有迭代器