0

您如何替换您遍历向量的位置?我试过类似的东西:

for(auto x : vect+2)

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

4

3 回答 3

6

如果您想使用基于范围的for,您可以使用Boost.Rangebegin() + 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 << " ";
    }
}
于 2013-04-17T20:29:32.223 回答
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 << " ";
        }
    );
}
于 2013-04-17T20:37:46.357 回答
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;
        }
    };
}
于 2013-04-17T21:11:17.280 回答