在迭代矢量时移位位置

时间:2013-04-17 20:23:14

标签: c++ c++11

如何替换迭代矢量的位置?我尝试过类似的东西:

for(auto x : vect+2)

但这不起作用。我确信这是一个简单的决心,但我无法在网上找到任何东西。

3 个答案:

答案 0 :(得分:6)

如果您想使用基于范围的for,可以使用Boost.Range创建一个从矢量的第三个元素(begin() + 2)开始的范围:

for (auto x : boost::make_iterator_range(begin(v) + 2, end(v)))
{
    std::cout << x << " ";
}

这是一个简单的例子:

#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>

int main()
{
    std::vector<int> v(10);
    iota(begin(v), end(v), 1);

    for (auto x : boost::make_iterator_range(begin(v) + 2, end(v)))
    {
        std::cout << x << " ";
    }
}

如果您想遍历每个第二个元素,您可以按如下方式更改范围:

namespace rng = boost::adaptors;
for (auto x : v | rng::strided(2))
{
    std::cout << x << " ";
}

在完整的程序中将是:

#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>

int main()
{
    namespace rng = boost::adaptors;

    std::vector<int> v(10);
    iota(begin(v), end(v), 1);

    for (auto x : v | rng::strided(2))
    {
        std::cout << x << " ";
    }
}

Boost.Range非常灵活,所以您可以将组合上面的两个适配器:

for (auto x : boost::make_iterator_range(begin(v) + 2, end(v)) |
              rng::strided(3))
{
    std::cout << x << " ";
}

如果您不想或不能使用Boost,可以使用带迭代器的经典for循环:

for (auto i = begin(v) + 2; i != end(v); ++i)
{
    std::cout << *i << " ";
}

这就是整个程序的样子:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> v(10);
    iota(begin(v), end(v), 1);

    for (auto i = begin(v) + 2; i != end(v); ++i)
    {
        std::cout << *i << " ";
    }
}

答案 1 :(得分:1)

这可以非常简单地实现,并且有许多适合任何编程风格的解决方案。

经典方法

int main()
{    
    std::vector<int> v(10);
    std::iota(v.begin(), v.end(), 1);

    for (auto i = v.begin() + 2; i != v.end(); ++i)
    {
        std::cout << *i << " ";
    }
}

功能方法

int main()
{    
    std::vector<int> v(10);
    std::iota(v.begin(), v.end(), 1);

    std::for_each(v.begin() + 2, v.end(), [](int val)
        {
            std::cout << val << " ";
        }
    );
}

答案 2 :(得分:0)

您可以添加一个光包装,使其适用于基于范围的:

#include <iostream>
#include <vector>
#include <iterator>

namespace range
{
    template <typename C>
    struct make_range
    {
        C t;
        make_range(C t, int offset)
        : t(std::begin(t) + offset, std::end(t))
        {}
        auto begin() -> decltype(t.begin())
        {
            return t.begin();
        }
        auto end() -> decltype(t.end())
        {
            return t.end();
        }
    };
}

int main()
{
    std::vector<int> v{1, 2, 3, 4, 5}; 
    for (auto i : range::make_range<decltype(v)>(v, 2))
    {
        std::cout << i << std::endl;
    }
}

也许最好只存储迭代器:

namespace range
{
    template <typename C>
    struct make_range
    {
        typename C::iterator beg_iter;
        typename C::iterator end_iter;
        make_range(C& t, int offset)
        : beg_iter(std::begin(t) + offset),  end_iter(std::end(t))
        {}
        auto begin() -> decltype(beg_iter)
        {
            return beg_iter;
        }
        auto end() -> decltype(end_iter)
        {
            return end_iter;
        }
    };
}