gpt4 book ai didi

c++ - 与 View 一起使用的自定义容器类型的要求

转载 作者:行者123 更新时间:2023-12-03 06:50:12 26 4
gpt4 key购买 nike

我开始玩 std::ranges并想了解 View 的真正工作原理。所以我尝试编写自己的容器和迭代器类型,并希望在 View 中使用它。
但似乎缺少一些东西,但编译器只告诉我没有 begin() View 中的方法,但不是为什么。
例子:

#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: error: 'struct std::ranges::views::__adaptor::_RangeAdaptorClosurestd::ranges::views::__adaptor::_RangeAdaptor<_Callable::operator()<{MyFixedContainer&, main()::<lambda(int)>&}>::<lambda(_Range&&)> >' has no member named 'begin'90 | auto b = y.begin();


https://godbolt.org/z/doW76j

最佳答案

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,错误信息会更清楚您的容器/迭代器必须建模的每个概念。

    关于c++ - 与 View 一起使用的自定义容器类型的要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63790108/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com