如何解决与视图一起使用的自定义容器类型的要求
我开始玩std::ranges
,并想了解视图的实际工作原理。因此,我尝试编写自己的容器和迭代器类型,并希望在视图中使用它。
但是似乎缺少了一些东西,但是编译器只告诉我视图内没有begin()
方法,而不是为什么。
示例:
#include <iostream>
#include <array>
#include <ranges>
class MyFixedContainer;
class MyIterator
{
MyFixedContainer* ptr;
unsigned int offset;
public:
MyIterator( MyFixedContainer* ptr_,unsigned int offset_ ): ptr{ ptr_},offset{offset_}{}
bool operator==( MyIterator& other ) const
{
return ( ptr == other.ptr )&& ( offset == other.offset );
}
bool operator!=( MyIterator& other ) const
{
return !(*this == other);
}
MyIterator operator++()
{
offset++;
return *this;
}
MyIterator operator++(int)
{
MyIterator tmp = *this;
offset++;
return tmp;
}
int operator*() const;
};
class MyFixedContainer
{
std::array<int,4> arr={5,6,7,8};
public:
auto begin() { return MyIterator{ this,0 }; }
auto end() { return MyIterator{ this,4}; }
int Get( int offset ) const
{
return arr[ offset ];
}
};
int MyIterator::operator*() const
{
return ptr->Get( offset );
}
int main()
{
MyFixedContainer c;
// Container type itself works:
for ( int i: c )
{
std::cout << i << std::endl;
}
// Try to use with std::ranges
auto even = [] (int i) { return 0 == i % 2; };
auto y = std::views::filter(c,even);
auto b = y.begin(); // << error message
}
编译为
main.cpp:90:16:错误:'struct std :: ranges :: views :: __ adaptor :: __ RangeAdaptorClosurestd :: ranges :: views :: __ adaptor :: _ RangeAdaptor <_callable :: operator>&}> ::
>'没有名为'begin'的成员 90 |自动b = y.begin();
解决方法
MyIterator
不为std::input_or_output_iterator
建模,因为:
- 它必须是默认可构造的。
-
std::iter_difference_t<MyIterator>
必须有效,并且 - 预递增运算符必须返回引用。
MyIterator
不是std::sentinel_for
<MyIterator,MyIterator>
,因为它的运算符==
和!=
采用引用而不是const
引用。
MyIterator
不满足std::input_iterator
,这要求std::iter_value_t
是有效的。
修复以上所有问题:
#include <iostream>
#include <array>
#include <ranges>
class MyFixedContainer;
class MyIterator
{
MyFixedContainer* ptr;
unsigned int offset;
public:
using difference_type = int;
using value_type = int;
MyIterator() = default;
MyIterator( MyFixedContainer* ptr_,unsigned int offset_ ): ptr{ ptr_},offset{offset_}{}
bool operator==( MyIterator const & other ) const
{
return ( ptr == other.ptr )&& ( offset == other.offset );
}
bool operator!=( MyIterator const & other ) const
{
return !(*this == other);
}
MyIterator &operator++()
{
offset++;
return *this;
}
MyIterator operator++(int)
{
MyIterator tmp = *this;
offset++;
return tmp;
}
int operator*() const;
};
class MyFixedContainer
{
std::array<int,4> arr={5,6,7,8};
public:
auto begin() { return MyIterator{ this,0 }; }
auto end() { return MyIterator{ this,4}; }
int Get( int offset ) const
{
return arr[ offset ];
}
};
int MyIterator::operator*() const
{
return ptr->Get( offset );
}
int main()
{
MyFixedContainer c;
// Container type itself works:
for ( int i: c )
{
std::cout << i << std::endl;
}
// Try to use with std::ranges
auto even = [] (int i) { return 0 == i % 2; };
static_assert(std::input_or_output_iterator<MyIterator>);
static_assert(std::ranges::input_range<MyFixedContainer>);
auto y = c | std::views::filter(even);
auto b = y.begin(); // << OK
}
如果您static_assert
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"bool": {
"must": [
[
{
"term": {
"section": "205"
}
},{
"term": {
"profile": "40"
}
},{
"term": {
"rim_size": "17"
}
}
]
]
}
}
]
}
},{
"bool": {
"should": [
[
{
"term": {
"supplier_id": 3
}
}
]
]
}
}
]
}
},
容器/迭代器必须建模的每个概念,错误消息就会更加清楚。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。