c – 具有复杂值类型的迭代器:与value_type和引用混淆

c – 具有复杂值类型的迭代器:与value_type和引用混淆,第1张

概述我想创建一个自定义迭代器包装器,例如,枚举:给定一对类型为T的迭代器,它将返回一个可迭代的类型std :: pair< const int,T&>,其中该对的第一个元素将取值0,1,2,依此类推. 我有一个问题,弄清楚什么应该是value_type和我的迭代器的引用.我想支持两种行为: 首先,引用基础序列的值: for (auto& kv: enumerate(my_vec)) { kv. 我想创建一个自定义迭代器包装器,例如,枚举:给定一对类型为T的迭代器,它将返回一个可迭代的类型std :: pair< const int,T&>,其中该对的第一个元素将取值0,1,2,依此类推.

我有一个问题,弄清楚什么应该是value_type和我的迭代器的引用.我想支持两种行为:

首先,引用基础序列的值:

for (auto& kv: enumerate(my_vec)) {    kv.second = kv.first;}

(有点std :: iota);

第二,制作价值的副本:

std::vector<int> a{10,20,30};auto copy = *enumerate(a).begin();a[0] = 15;std::cout << copy.first << " " << copy.second; // 0 10

我很困惑应该是Iterator :: operator *()的返回类型.如果它是std :: pair< const int,T&>然后在第二个示例中,不会复制值.如果它是std :: pair< const int,则T>那么在第一个例子中,不可能引用基础值.我该怎么做以及这个迭代器的value_type,reference和pointer typedef应该是什么?

这是我尝试实现它.它支持获取引用但不支持复制.

template<typename T>struct Iterator {    using TT = typename std::iterator_traits<T>::value_type;    using value_type = std::pair<const int,TT>;    using reference = std::pair<const int&,typename std::iterator_traits<T>::reference>;    using pointer = value_type*;    using iterator_category = std::forward_iterator_tag;    using difference_type = std::ptrdiff_t;    std::pair<int,T> it;    Iterator(T iterator) : it(0,iterator) {}    bool operator==(const Iterator& other) const { return it.second == other.it.second; }    bool operator!=(const Iterator& other) const { return it.second != other.it.second; }    reference operator*() { return { it.first,*it.second }; }    Iterator& operator++() { ++it.first; ++it.second; return *this; }};

附:我刚刚检查过,boost :: adapters :: index遇到了同样的问题并且没有复制该值.

解决方法 这个问题类似于std :: vector< bool>,你想提供一个代理,它就像一个引用,但也支持值语义.

然而,有所不同的是,涉及的类型不受限制,涉及两个参考,并且d出各种毛羽.以下是部分实现,它说明了您遇到的一些问题

#include<iterator>#include<functional>template<typename F,typename S,bool defined = true>struct sfinae_difference_type {};template<typename F,typename S>struct sfinae_difference_type<F,S,std::is_same_v<typename std::iterator_traits<F>::difference_type,typename std::iterator_traits<S>::difference_type>>{    using difference_type = typename std::iterator_traits<F>::difference_type;};template<typename F,typename S>class pair_iterator : sfinae_difference_type<F,S>{    using Fvalue_type = typename std::iterator_traits<F>::value_type;    using Svalue_type = typename std::iterator_traits<S>::value_type;    using Freference = typename std::iterator_traits<F>::reference;    using Sreference = typename std::iterator_traits<S>::reference;    F f;    S s;public:    using value_type = std::pair<Fvalue_type,Svalue_type>;    struct reference    {        Freference first;        Sreference second;        reference() = delete;        reference(const reference& other) : first{other.first},second{other.second} {}         reference& operator=(const reference& rhs)        {            first = rhs.first;            second = rhs.second;            return *this;        }        operator value_type() { return {f,s}; }    private:        reference(Freference f,Sreference s) : first{f},second{s} {}        frIEnd pair_iterator;    };    struct pointer    {        // similar to reference    };    pair_iterator() = default;    pair_iterator(const pair_iterator&) = default;    pair_iterator(F f,S s) : f{f},s{s} {}    pair_iterator& operator++() { ++f; ++s; return *this; }    reference operator*() { return {*f,*s}; }    pointer operator->() { return {f.operator->(),s.operator->()}; }    bool operator==(const pair_iterator& other)    {        return f == other.f && s == other.s;    }};

然后你用它作为

#include<vector>#include<List>#include<iostream>int main(){    std::vector v{1,3,4,5};    std::List l{6,7,8,9,10};    pair_iterator begin{v.begin(),l.begin()},end{v.end(),l.end()};    for(; begin != end; ++begin)        std::cout << begin->first << ' ' << begin->second << '\n';}

Live

一些直接明显的问题:

>实施繁琐.有sfinae友好型别名和适当的代理需要丰富的样板.
>代理的语义可能令人困惑.复制/分配一个引用到另一个是什么意思?什么是自动is_this_a_copy = *它应该做什么?
>平等意味着什么?两个内部迭代器是否必须相等?这打破了与最终迭代器的比较.

所有这些必须被敲定以使其工作,并没有一个简单的答案.

总结

以上是内存溢出为你收集整理的c – 具有复杂值类型的迭代器:与value_type和引用混淆全部内容,希望文章能够帮你解决c – 具有复杂值类型的迭代器:与value_type和引用混淆所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/1229056.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存