![](/img/trans.png)
[英]Is string::iterator necessarily a random_access_iterator?
[英]c++20 template parameter of random_access_iterator concept, cannot accept iterator type?
对于 c++ 20 概念,我进行了快速测试:
#include<iostream>
#include<vector>
using namespace std;
template <random_access_iterator I>
void advance(I &iter, int n) {
cout << "random_access_iterator" << '\n';
}
int main() {
vector vec{1, 2, 3};
{
vector<int>::iterator itRa = vec.begin();
advance(itRa, 2);
}
advance(vec.begin(), 3); // compilation error!
return 0;
}
我在 windows10 上运行 clang++ 14 并打印:
clang++ .\MyAdvance.cpp -std=c++20
candidate function [with _InIt =
std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>, _Diff =
int] not viable: expects an lvalue for 1st argument
_CONSTEXPR17 void advance(_InIt& _Where, _Diff _Off) { // increment iterat...
^
.\MyAdvance.cpp:6:6: note: candidate function [with I =
std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>] not
viable: expects an lvalue for 1st argument
void advance(I &iter, int n) {
^
1 error generated.
很奇怪,有什么区别:
vector<int>::iterator itRa = vec.begin();
advance(itRa, 2);
和
advance(vec.begin(), 3); // compilation error!
为什么第一个版本被编译而第二个版本没有?
begin()
按值返回迭代器,这意味着调用表达式是纯右值。 您不能将纯右值作为参数传递给非const
左值引用参数。 这并不特定于迭代器。 它适用于任何类型,例如
void f(int&);
//...
f(1234); // fails because 1234 is a prvalue
为了也允许prvalues作为参数,您需要添加另一个重载I&&
而不是I&
参数类型:
template <random_access_iterator I>
void advance(I &&iter, int n) {
cout << "random_access_iterator" << '\n';
}
但这没有任何意义。 为什么应该允许推进一个迭代器,然后立即销毁? 如果有人写了advance(vec.begin(), 3)
那么那一定是一个错误,它产生一个错误是好的,因为那个表达式根本没有效果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.