Range-v3:使用view_facade提供const和非const迭代器 [英] Range-v3: Use view_facade to provide both const and non-const iterators

查看:943
本文介绍了Range-v3:使用view_facade提供const和非const迭代器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法使用view_facade(从 range-v3 )创建一个提供const和non- const访问。作为一个例子,我尝试修改view_facade测试(在test / view_facade.cpp)允许非const访问(默认情况下它只允许const访问):

I am having trouble using view_facade (from range-v3) to create a view that provides both const and non-const access. As an example, I tried modifying the view_facade test (in test/view_facade.cpp) to allow non-const access (by default it only allows const access):

struct MyRange
  : ranges::range_facade<MyRange>
{
private:
    friend struct ranges::range_access;
    std::vector<int> ints_;

    template <bool isConst>
    struct cursor
    {
    private:
        using It = typename std::conditional<isConst, std::vector<int>::const_iterator, std::vector<int>::iterator>::type;
        using RefType = typename std::conditional<isConst, int const&, int&>::type;
        It iter;
    public:
        cursor() = default;
        cursor(It it)
          : iter(it)
        {}
        RefType current() const
        {
            return *iter;
        }
    //...
    };
/*    // Uncommenting these overloads will cause an error, below.
    cursor<true> begin_cursor() const
    {
        return {ints_.begin()};
    }
    cursor<true> end_cursor() const
    {
        return {ints_.end()};
    }
*/
    cursor<false> begin_cursor()
    {
        return {ints_.begin()};
    }
    cursor<false> end_cursor()
    {
        return {ints_.end()};
    }
public:
    MyRange()
      : ints_{1, 2, 3, 4, 5, 6, 7}
    {}
};

int main() {
    MyRange nc;
    int& nci = *nc.begin();  // error here when const overloads present.
}

完整的代码在这里。

这很好用的begin_cursor和end_cursor的const重载注释掉。然而,如果我添加这些重载回来,在指示的行(GCC 5.1)生成以下错误:

This works fine with the const overloads of begin_cursor and end_cursor commented out. However, if I add those overloads back in, the following error is generated on the indicated line (GCC 5.1):

error: binding 'const int' to reference of type 'int&' discards qualifiers

似乎是选择const版本,给我一个const迭代器。我想要的是:const对象的const迭代器,非const对象的非const迭代器。如何实现这一点?

It seems to be selecting the const version, giving me a const iterator. What I want is: const iterators for const objects, and non-const iterators for non-const objects. How can I achieve that?

推荐答案

view_facade 视图指的是他们不拥有的数据。他们就像指针在逻辑上他们是indirections。和类似指针一样,顶层 const 应该 const 的数据。这是你是否取消引用 int * int * const ,结果是相同的: int&

view_facade is for building views. Views refer to data they don't own. They are like pointers in that logically they are indirections. And like pointers, top-level const should have no effect on the const-ness of the data referenced. That is whether you dereference an int* or an int*const, the result is the same: int&.

您的视图不是视图。它拥有其数据。 (请参阅 vector< int> ints _ 数据成员。)尝试使用 view_facade 将此数据结构转换为视图势必导致挫折。这是非常设计。视图与容器不同。

Your view is not a view. It owns its data. (See the vector<int> ints_ data member.) Trying to use view_facade to turn this data structure into a view is bound to lead to frustration. This is very much by design. Views are distinct from containers. The Range-v3 library doesn't come with a container facade, sorry.

(发生了什么:因为视图表示间接, view_facade 尝试非常难以使const和非const begin() end()相同类型,如果 cursor_begin()const 存在,那么总是选择 。混淆容器与视图。)

(What's going on: since views represent indirection, view_facade tries very hard to make const and non-const begin() and end() return the same types. If cursor_begin() const is present, that one is always chosen. Always. When this breaks code, it's generally because that code is confusing containers with views.)

这篇关于Range-v3:使用view_facade提供const和非const迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆