关于递增迭代器的困惑
Confusion about incrementing iterator
int main(){
multiset<string> graph;
graph.insert("a");
graph.insert("b");
multiset<string>::iterator it = graph.begin();
cout << *(it + 1) // Wrong
cout << *++it; // True
return 0;
}
为什么编译器在执行*(it + 1)
的时候会报错,但是*(++it)
却可以很好的执行。 it + 1
和 ++it
return 不应该是同一个值吗?
因为std::multiset
迭代器需要满足BidirectionalIterator的要求,也就是说必须支持operator++
和operator--
。没有要求支持其他操作,例如加法或减法。
迭代器是适合结构的对象,每个迭代器的工作方式不同取决于您使用的结构(映射、集合、矢量等)。
迭代器是用函数定义的,在 C++ 中你可以重载像 +,-,*,(),[],... 这样的运算符,所以可能定义的 ++ 函数不像运算符
+(iterator, int)
导致错误。
如果你支持+ 1
,你也必须支持+ N
。为了使编写低效代码变得更加困难,+ N
仅支持它在恒定时间内工作的迭代器(例如,它支持 std::vector
)。
RandomAccessIterators 允许您添加任意偏移量,如 it + n
,但 multiset
只有 BidirectionalIterators。有关迭代器类别的更多信息,请参见此处:https://en.cppreference.com/w/cpp/iterator#Iterator_categories.
原则上你是正确的,it+1
和 ++it
都将迭代器递增 1。如果迭代器支持 ++it
,它也可以支持 it+n
。然而,想法是 RandomAccessIterators 可以在常数时间内执行 it+n
,而不是 RandomAccessIterators 的迭代器将需要执行 n 次单增量。因为那是相当低效的,所以他们不支持开箱即用。
如果您想将非 RandomAccessIterator 递增超过 1
,您可以使用 std::next
or std::advance
。通过调用 std::next
/std::advance
代码更清楚地表明递增迭代器是一个潜在的昂贵操作,而 it + n
预计需要固定时间(因此当它不固定时不允许时间)。
int main(){
multiset<string> graph;
graph.insert("a");
graph.insert("b");
multiset<string>::iterator it = graph.begin();
cout << *(it + 1) // Wrong
cout << *++it; // True
return 0;
}
为什么编译器在执行*(it + 1)
的时候会报错,但是*(++it)
却可以很好的执行。 it + 1
和 ++it
return 不应该是同一个值吗?
因为std::multiset
迭代器需要满足BidirectionalIterator的要求,也就是说必须支持operator++
和operator--
。没有要求支持其他操作,例如加法或减法。
迭代器是适合结构的对象,每个迭代器的工作方式不同取决于您使用的结构(映射、集合、矢量等)。
迭代器是用函数定义的,在 C++ 中你可以重载像 +,-,*,(),[],... 这样的运算符,所以可能定义的 ++ 函数不像运算符
+(iterator, int)
导致错误。
如果你支持+ 1
,你也必须支持+ N
。为了使编写低效代码变得更加困难,+ N
仅支持它在恒定时间内工作的迭代器(例如,它支持 std::vector
)。
RandomAccessIterators 允许您添加任意偏移量,如 it + n
,但 multiset
只有 BidirectionalIterators。有关迭代器类别的更多信息,请参见此处:https://en.cppreference.com/w/cpp/iterator#Iterator_categories.
原则上你是正确的,it+1
和 ++it
都将迭代器递增 1。如果迭代器支持 ++it
,它也可以支持 it+n
。然而,想法是 RandomAccessIterators 可以在常数时间内执行 it+n
,而不是 RandomAccessIterators 的迭代器将需要执行 n 次单增量。因为那是相当低效的,所以他们不支持开箱即用。
如果您想将非 RandomAccessIterator 递增超过 1
,您可以使用 std::next
or std::advance
。通过调用 std::next
/std::advance
代码更清楚地表明递增迭代器是一个潜在的昂贵操作,而 it + n
预计需要固定时间(因此当它不固定时不允许时间)。