0

函数的定义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]

我想知道wy?

4

4 回答 4

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

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

为了让您的代码能够正常工作,请在同一个迭代器上使用advancecout

auto iter = vecStr.begin();
advance(iter , 2);
cout << *iter << endl;

只是原始代码中的注释,advance(vecStr.begin(), 2);实际上不会编译,至少如果您使用严格的编译器设置。vecStr.begin()返回一个临时对象,该对象不能绑定到其第一个参数std::advance是左值引用。


此外,std::vector::begin()逻辑上返回向量内实际开始迭代器的副本,而不是对其的引用。这意味着您对返回的迭代器所做的任何事情都不会反映到向量内的开始迭代器。我在这里谈论的是迭代器,而不是它们指向的元素。

于 2013-08-10T04:11:38.483 回答
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,有时称为邪恶扩展。

你应该做:

auto biter = vecStr.begin();    // biter points to begin of vecStr
std::advance(biter, 2);         // advance biter by 2 position
std::cout<< *biter << std::endl;
于 2013-08-10T04:11:34.193 回答
0

您的代码不能在符合标准的编译器下编译。我猜您正在使用 Visual Studio,并且您的警告级别还不够高,无法告诉您有关临时引用的信息。

vector::begin()不返回对迭代器的引用。它按值返回一个迭代器;它返回一个临时的。std::advance的第一个参数是非常量引用。在标准 C++ 中,这些是不允许绑定到临时参数的。所以你的代码无法编译。

但是在 VS 上,这是允许的,这不会做你想做的,因为你正在推进一个临时对象,而不是实际“存储”在vector. 毕竟,avector可能不会真正存储这些东西;它们可以从任意数据生成。所以你不能简单地修改 a 中的迭代器vector,因为 avector中可能没有迭代器

于 2013-08-10T04:22:27.680 回答
0

vector::begin()是一个返回迭代器的函数。您无法begin()通过修改它返回的迭代器来更改返回的内容 - 您只能通过修改向量内容来更改它返回的内容。

试试这个:

auto it = vecStr.begin();
advance(it, 2);
cout<<*(it)<<endl;
于 2013-08-10T04:10:30.843 回答