繁体   English   中英

c++20 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM