使用c ++ 11基于范围的for循环搜索插入位置

时间:2018-07-14 19:29:04

标签: c++ c++11 for-loop

我想知道天气是否有可能使用c ++ 11 <基于范围的基于循环的语法来搜索稍后在列表中使用的插入点。我可以通过使用c ++ 11 ranged-based-for-loop 语法以某种方式压缩for (auto i = l.begin(); i != l.end(); i++)吗?

#include <iostream>
#include <list>

int main(int argc, char **argv) {

    std::list<int> l = { 1, 2, 3, 5};

    for (auto i = l.begin(); i != l.end(); i++) {
        if (*i == 3) {
            l.insert(i, 4);
            break;
        }
    }

    for (auto &i : l) {
       std::cout << " " << i;
    }
};

使用伪代码,例如:

for (auto &i : l) {
    if (i == 3) {
        l.insert(some_magic_opertor(i), 4);
        break;
    }
}

或使用伪代码:

typedef std::list<int>::iterator it;
for (it i : l) {
    if (*i == 3) {
        l.insert(i, 4);
        break;
    }
}

2 个答案:

答案 0 :(得分:1)

这只有在您创建自己的精美迭代器适配器时才可能实现,该适配器在取消引用时将返回基础迭代器:

template <typename Iterator>
class exposed_iterator
{
public:
    exposed_iterator(Iterator it)
        : m_iterator(std::move(it)) { }
    Iterator &operator*()
    {
        return m_iterator;
    }

    exposed_iterator & operator++()
    {
        ++m_iterator;
        return *this;
    }

    bool operator!=(const exposed_iterator &that) const
    {
        return m_iterator != that.m_iterator;
    }

private:
    Iterator m_iterator;
};

然后提供一个函数和不方便的标准range类,以在基于范围的for循环中使用:

template <typename Iterator>
struct range //struct for the sake of simplicity
{
    Iterator m_begin;
    Iterator m_end;

    Iterator begin() const { return m_begin; }
    Iterator end() const { return m_end; }
};

template <typename Container, typename Iterator = typename Container::iterator>
range<exposed_iterator<Iterator>> expose(Container &container)
{
    return { container.begin(), container.end() };
}

然后按以下方式使用所有这些机器:

std::list<int> l = { 1, 2, 3, 5};
for (auto &&it : expose(l)) {
    if (*it > 3) {
        l.insert(it, 4);
        break;
    }
}

答案 1 :(得分:0)

您确实可以做到这一点,例如,通过创建一个额外的变量来保存您当前所处的位置,或者使用std::find,如下所示:

int i = 0;
for (auto& iter : l) {
    if (i == 3) { /* do something */; break; }
    //...
    ++i;
}


auto iter = l.find( /* find condition */ )
if (iter == l.end()) {
    // handle not-found case
}
else {
    // do something
}

但是,这种方法违反了基于范围的for循环的目的,不需要需要索引,因此最好使用常规的for循环。< / p>