加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 我可以从基于循环的范围内获取项目的索引吗?

发布时间:2020-12-16 10:51:24 所属栏目:百科 来源:网络整理
导读:我已经定义了一个像这样的指针deque: std::dequeBoardSquare * mydeque; 我想在我的双端队列中使用基于范围的循环: for (BoardSquare * b : mydeque) { // do something involving the index of b} 是否有可能从基于循环的范围内获取项目的索引? 解决方法
我已经定义了一个像这样的指针deque:

std::deque<BoardSquare *> mydeque;

我想在我的双端队列中使用基于范围的循环:

for (BoardSquare * b : mydeque) {

    // do something involving the index of b
}

是否有可能从基于循环的范围内获取项目的索引?

解决方法

我提出了一个解决方案 – 或者说是一个实验性解决方案.以下是您最终将如何使用它:

for(auto item : make_indexable(v))
{
      //std::get<0>(item) is the index
      //std::get<1>(item) is the object
}

这里是最小的实现(它只是为了演示基本的想法):

#include <tuple>
#include <functional>

template<typename C>
struct indexed_container
{
    struct indexed_iterator
    {
        typedef typename C::value_type value_type;
        typedef std::tuple<size_t,std::reference_wrapper<value_type>> tuple_type;

        typename C::iterator _it;
        size_t _index;

        indexed_iterator(typename C::iterator it) : _it(it),_index(0) {}

        indexed_iterator& operator++()
        {
            ++_it;
            ++_index;
            return *this;
        }
        bool operator == (indexed_iterator const & other)
        {
            return _it == other._it;
        }
        bool operator != (indexed_iterator const & other)
        {
            return _it != other._it;
        }
        tuple_type operator*()
        {
            return std::make_tuple(_index,std::ref(*_it));
        }
    };

    indexed_container(C & c) : _c(c) {}

    indexed_iterator begin()
    {
        return indexed_iterator(_c.begin());
    }
    indexed_iterator end()
    {
        return indexed_iterator(_c.end());
    }
private:
    C & _c;
};

template<typename C>
auto make_indexable(C & c) -> indexed_container<C>
{
    return indexed_container<C>(c); 
}

测试代码:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v{1,2,3};
    for(auto item : make_indexable(v))
    {
        std::cout << std::get<0>(item) << " => " << std::get<1>(item) << std::endl;

        std::get<1>(item) *= 10; //modify value!
    }
    std::cout << "nModifiedn";
    for(auto item : make_indexable(v))
    {
        std::cout << std::get<0>(item) << " => " << std::get<1>(item) << std::endl;
    }
}

输出:

0 => 1
1 => 2
2 => 3

Modified
0 => 10
1 => 20
2 => 30

Online demo

请注意,此解决方案并不完美,因为它不适用于临时和const容器(以及const对象的容器).此外,即使您编写自动项而不是auto&,也会立即返回基础对象作为参考. item(事实上,你不能写auto& item).但我认为这些问题可以通过更多努力和精心设计来解决.毕竟,这只是一个基本想法的示范.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读