首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用for-range循环进行切片?C++0x

如何使用for-range循环进行切片?C++0x
EN

Stack Overflow用户
提问于 2010-02-04 06:54:37
回答 2查看 3.3K关注 0票数 8

在C++0X中使用基于范围的循环,我知道我们将能够做到:

代码语言:javascript
复制
std::vector<int> numbers = generateNumbers();

for( int k : numbers )
{
   processNumber( k );
}

(使用lambda编写可能会更简单)

但是,如果我只想将processNumber( K)应用于数字的一部分,我应该怎么做?例如,我应该如何编写这个For循环,以便将processNumber()应用到数字的一半(头或尾)?像Python或Ruby一样允许“切片”吗?

EN

回答 2

Stack Overflow用户

发布于 2011-05-29 19:17:56

您可以使用Boost.Range库中的"slicedrange adaptor

代码语言:javascript
复制
#include <boost/range/adaptor/sliced.hpp>

using boost::adaptors::sliced;

..。

代码语言:javascript
复制
std::vector<int> numbers = generateNumbers();
for( int k : numbers | sliced(0, numbers.size() / 2))
{
     processNumber( k );
}   
票数 13
EN

Stack Overflow用户

发布于 2010-02-06 20:15:58

一种可能是boost的iterator_range

(没有支持基于范围的的编译器,而是使用BOOST_FOREACH。我希望基于范围的工作是相同的,只要容器或范围具有begin和end方法。)

代码语言:javascript
复制
#include <boost/foreach.hpp>
#include <boost/range/iterator_range.hpp>
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    BOOST_FOREACH(int n, boost::make_iterator_range(v.begin(), v.begin() + v.size() / 2)) {
        std::cout << n << '\n';
    }
}

为了方便起见,您还可以制作自己的切片函数,这样它就可以接受索引而不是迭代器。同样,它可能基于boost.iterator_range,也可能不是:

代码语言:javascript
复制
#include <cstddef>
#include <iterator>

template <class Iterator>
class iter_pair
{
public:
    typedef Iterator iterator;
    typedef Iterator const_iterator; //BOOST_FOREACH appears to want this
    iter_pair(iterator first, iterator last): first(first), last(last) {}
    iterator begin() const { return first; }
    iterator end() const { return last; }
private:
    iterator first, last;
};

template <class Container>
struct iterator_type
{
    typedef typename Container::iterator type;
};

template <class Container>
struct iterator_type<const Container>
{
    typedef typename Container::const_iterator type;
};

template <class Container>
iter_pair<typename iterator_type<Container>::type>
    slice(Container& c, size_t i_first, size_t i_last)
{
    typedef typename iterator_type<Container>::type iterator;
    iterator first = c.begin();        
    std::advance(first, i_first);
    iterator last = first;
    std::advance(last, i_last - i_first);
    return iter_pair<iterator>(first, last);
}

template <class Container>
iter_pair<typename iterator_type<Container>::type>
    slice(Container& c, size_t i_last)
{
    return slice(c, 0, i_last);
}

//could probably also be overloaded for arrays

#include <cctype>
#include <string>
#include <boost/foreach.hpp>
#include <iostream>

int main()
{
    std::string s("Hello world, la-la-la!");
    BOOST_FOREACH( char& c, slice(s, 2, 11)) {
        if (c == 'l')
            c = std::toupper(c);
    }
    const std::string& r = s;
    BOOST_FOREACH( char c, slice(r, r.size() - 1) ) {
        std::cout << c << " ";
    }
    std::cout << '\n';
}

通常情况下,人们可能会首先使用迭代器,所以它可能没有那么有用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2196138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档