Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Range-v3:使用view_facade提供常量和非常量迭代器_C++_Range V3 - Fatal编程技术网

C++ Range-v3:使用view_facade提供常量和非常量迭代器

C++ Range-v3:使用view_facade提供常量和非常量迭代器,c++,range-v3,C++,Range V3,我在使用view_facade(from)创建同时提供常量和非常量访问的视图时遇到问题。例如,我尝试修改视图外观测试(在test/view\u facade.cpp中)以允许非常量访问(默认情况下,它只允许常量访问): 它似乎选择了常量版本,给了我一个常量迭代器。我想要的是:常量对象的常量迭代器,非常量对象的非常量迭代器。如何实现这一点?视图\u facade用于建筑视图。视图指的是它们不拥有的数据。它们就像指针,在逻辑上它们是间接的。和指针一样,顶级的const应该不会影响引用数据的const

我在使用view_facade(from)创建同时提供常量和非常量访问的视图时遇到问题。例如,我尝试修改视图外观测试(在test/view\u facade.cpp中)以允许非常量访问(默认情况下,它只允许常量访问):


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

视图\u facade
用于建筑视图。视图指的是它们不拥有的数据。它们就像指针,在逻辑上它们是间接的。和指针一样,顶级的
const
应该不会影响引用数据的
const
-ness。这就是无论您取消引用
int*
还是
int*const
,结果都是相同的:
int&

你的观点不是一个观点。它拥有自己的数据。(请参阅
vector ints_u
数据成员。)试图使用
view_facade
将此数据结构转换为视图必然会导致失败。这是精心设计的。视图不同于容器。抱歉,Range-v3库没有容器外观


(发生了什么:由于视图表示间接性,
view\u facade
非常努力地使常量和非常量
begin()
end()
返回相同的类型。如果
cursor\u begin())const
存在,总是选择一个。总是。当这破坏了代码时,通常是因为代码混淆了容器和视图。)

我想我不明白视图不拥有其数据意味着什么。我发布的示例基本上是直接从测试中得到的,但我实际上试图做的是将指针+大小包装在一个类似范围的接口中。由于视图不会拥有分配/取消分配数据(由第三方库管理)意义上的指针,因此我认为视图外观是合适的。但是,你的解释是有道理的。感谢您的回答。指针/长度对是一个视图<代码>视图::计数正是这样。如果你用指针/长度替换你的
向量
成员,事情应该会好得多。啊<代码>视图::计数
就是一个完美的例子。不知道我是怎么错过的。“当这破坏了代码时,通常是因为代码……”已经被破坏了。尽管容器适配器很有趣也很有用(例如参见
std::stack
),但我不确定现在是进一步扩展range-v3范围的适当时机。我希望花更多的时间去完善和提出已经存在的东西,而不是花更少的时间去添加我需要维护的新特性。
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.
}
error: binding 'const int' to reference of type 'int&' discards qualifiers