如何使我的容器与 boost::range 兼容?

How can I make my container compatible with boost::range?

提问人:CrouchEndTiger 提问时间:3/15/2022 最后编辑:CrouchEndTiger 更新时间:3/16/2022 访问量:281

问:

我正在滚动一个自定义的、类似标准的容器,我希望它与库兼容。boost::range

到目前为止,它适用于所有 STL 算法,并且还满足以下条件:

BOOST_CONCEPT_ASSERT((boost::InputIterator<my_container::const_iterator>));
BOOST_CONCEPT_ASSERT((boost::Container<my_container>));

但是当我尝试在这种情况下使用它时:

auto r = c | boost::adaptors::indexed();

它似乎缺少一些模板化的元数据。错误如下

error: no type named 'type' in boost::range::iterator<my_container, void>
>> typename range_iterator<SinglePassRange>::type

是否有类似的概念断言可以用来帮助我完成我的类型的缺失实现?或者甚至是一篇解释如何使容器兼容的文章?我假设我不需要在我的实现中实际包含升压类型,因为 STL 显然不需要。boost::range

任何帮助非常感谢!:-)

编辑:最小(ish)示例

#include <catch2/catch.hpp>

#include <boost/concept_check.hpp>
#include <boost/concept/assert.hpp>
#include <boost/range/adaptor/indexed.hpp>

#include <algorithm>

SCENARIO("container")
{
    class my_container
    {
    public:
        class const_iterator
        {
        public:
            using value_type = const int;
            using pointer = const int*;
            using reference = const int&;
            using difference_type = std::ptrdiff_t;
            using iterator_category = std::input_iterator_tag;
            const_iterator() = default;
            bool operator==(const_iterator other) const noexcept { return d == other.d; }
            bool operator!=(const_iterator other) const noexcept { return !(*this == other); }
            reference operator*() const { return *d; }
            pointer operator->() const { return d; }
            const_iterator& operator++() { ++d; return *this; }
            const_iterator operator++(int) { return d++; }
        private:
            friend my_container;
            const_iterator(const int* p) : d(p) {}
            const int* d{nullptr};
        };
        using value_type = int;
        using const_reference = const int&;
        using const_pointer = const int*;
        using size_type = std::size_t;
        using difference_type = std::ptrdiff_t;
        my_container() : data({0, 1, 2, 3, 4}) {}
        const_iterator begin() const { return const_iterator(data.data()); }
        const_iterator end() const { return const_iterator(data.data() + 5); }
        size_type size() const { return 5; }
        size_type max_size() const { return 5; }
        bool empty() const { return false; }
    private:
        std::array<int, 5> data;
    };

    BOOST_CONCEPT_ASSERT((boost::InputIterator<my_container::const_iterator>));
    BOOST_CONCEPT_ASSERT((boost::Container<my_container>));

    GIVEN("a container") {
        my_container container;
        WHEN("use std::algorithms") {
            auto itr = std::find(container.begin(), container.end(), 3);
            THEN("element is found") {
                CHECK(itr != container.end());
            }
        }
        WHEN("use boost range") {
            // wont compile
            auto r = container | boost::adaptors::indexed();
        }
    }
}
C++ 加速 提升范围

评论

0赞 Jerry Jeremiah 3/15/2022
根据 boost.org/doc/libs/1_39_0/libs/range/doc/boost_range.html 任何标准(如容器)都可以使用。但我不知道你的容器与标准容器有何不同。
1赞 Dmytro Ovdiienko 3/15/2022
您能否提供一个最小的代码来重现该问题?
0赞 CrouchEndTiger 3/16/2022
感谢您的观看!我添加了一个最小的复制品。的问题。
0赞 ecatmur 3/16/2022
你不需要吗?iteratorconst_iterator

答:

2赞 ecatmur 3/16/2022 #1

您需要以及 .尝试:iteratorconst_iterator

    using iterator = const_iterator;