简体   繁体   English

Range-V3:获取基本迭代器

[英]Range-V3: get base iterator

I try to use Range-V3 library (for MSVC), but due to lack of documentation I don't understand how to do one thing. 我尝试使用Range-V3库(用于MSVC),但由于缺少文档,我不明白如何做一件事。

std::map<int, std::wstring> ss = { {1,L"1"}, {2,L"2"}, {3,L"3"} };
auto rng = ss | ranges::view::reverse | ranges::view::values;
auto it = ranges::find_if(rng, [](auto&&x) {return x == L"2"; });
if (it != rng.end()) {
    assert(it.base()->first == 2); // this does not compile
}

What do I get from find_if ? 我从find_if得到什么? Is this iterator? 这是迭代器吗? I want to get an iterator to base element, ie to value in ss map. 我想得到一个基本元素的迭代器,即在ss map中的值。

Here is the error I get: 这是我得到的错误:

1>d:\sources\ranges_test\ranges_test.cpp(11): error C2819: type 'ranges::v3::basic_iterator<ranges::v3::adaptor_cursor<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,ranges::v3::reverse_view<ranges::v3::sized_range<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>>>::adaptor<true>>,ranges::v3::adaptor_cursor<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,ranges::v3::reverse_view<ranges::v3::sized_range<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>>>::adaptor<true>>>' does not have an overloaded member 'operator ->'
1>        with
1>        [
1>            _Kty=int,
1>            _Ty=std::wstring
1>        ]
1>d:\sources\fingrad\dev.fingrad\src\vc\lib\range\v3\utility\basic_iterator.hpp(656): note: see declaration of 'ranges::v3::basic_iterator<ranges::v3::adaptor_cursor<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,ranges::v3::reverse_view<ranges::v3::sized_range<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>>>::adaptor<true>>,ranges::v3::adaptor_cursor<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,ranges::v3::reverse_view<ranges::v3::sized_range<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>>>::adaptor<true>>>'
1>        with
1>        [
1>            _Kty=int,
1>            _Ty=std::wstring
1>        ]
1>d:\sources\ranges_test\ranges_test.cpp(11): note: did you intend to use '.' instead?
1>d:\sources\ranges_test\ranges_test.cpp(11): error C2039: 'first': is not a member of 'ranges::v3::basic_iterator<ranges::v3::adaptor_cursor<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,ranges::v3::reverse_view<ranges::v3::sized_range<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>>>::adaptor<true>>,ranges::v3::adaptor_cursor<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,ranges::v3::reverse_view<ranges::v3::sized_range<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>>>::adaptor<true>>>'
1>        with
1>        [
1>            _Kty=int,
1>            _Ty=std::wstring
1>        ]
1>d:\sources\fingrad\dev.fingrad\src\vc\lib\range\v3\utility\basic_iterator.hpp(656): note: see declaration of 'ranges::v3::basic_iterator<ranges::v3::adaptor_cursor<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,ranges::v3::reverse_view<ranges::v3::sized_range<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>>>::adaptor<true>>,ranges::v3::adaptor_cursor<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,ranges::v3::reverse_view<ranges::v3::sized_range<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>>>::adaptor<true>>>'
1>        with
1>        [
1>            _Kty=int,
1>            _Ty=std::wstring
1>        ]

This looks like a bug 1 in MSVC implementation of range-V3 (or rather a missing feature). 这看起来像是MSVC实现范围V3中的错误1 (或者更确切地说是缺失的功能)。 An easy workaround would be to replace your code with: 一个简单的解决方法是用以下代码替换您的代码:

assert((*it.base()).first == 2);

This should work because operator* is overload for basic_iterator while operator-> was not. 这应该有效,因为operator* operator-> basic_iterator重载,而operator->不是。


1 If you look at MSVC source for basic_iterator , you will notice that there are no overload for operator-> , while there is one in the original range-v3 basic_iterator . 1如果您查看basic_iterator MSVC源basic_iterator ,您会注意到operator->没有重载,而原始范围basic_iterator有一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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