亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

C ++ 11基于反向范圍的for循環

C ++ 11基于反向范圍的for循環

C++
catspeake 2019-10-15 09:16:40
是否有一個容器適配器可以顛倒迭代器的方向,以便我可以使用基于范圍的for循環反向迭代容器?使用顯式迭代器,我可以將其轉換為:for (auto i = c.begin(); i != c.end(); ++i) { ...到這個:for (auto i = c.rbegin(); i != c.rend(); ++i) { ...我想將其轉換為:for (auto& i: c) { ...對此:for (auto& i: std::magic_reverse_adapter(c)) { ...有這樣的事情還是我必須自己寫?
查看完整描述

3 回答

?
慕尼黑8549860

TA貢獻1818條經驗 獲得超11個贊

實際上,Boost確實具有這樣的適配器:boost::adaptors::reverse。


#include <list>

#include <iostream>

#include <boost/range/adaptor/reversed.hpp>


int main()

{

    std::list<int> x { 2, 3, 5, 7, 11, 13, 17, 19 };

    for (auto i : boost::adaptors::reverse(x))

        std::cout << i << '\n';

    for (auto i : x)

        std::cout << i << '\n';

}


查看完整回答
反對 回復 2019-10-15
?
拉丁的傳說

TA貢獻1789條經驗 獲得超8個贊

實際上,在C ++ 14中,只需幾行代碼即可完成。


這在思想上與@Paul的解決方案非常相似。由于C ++ 11中缺少某些內容,因此該解決方案有點不必要地過大(加上在std氣味中定義)。感謝C ++ 14,我們可以使它更具可讀性。


關鍵的觀察結果是,基于范圍的for循環通過依賴begin()和end()來獲取范圍的迭代器而工作。由于ADL,一個甚至不需要定義自己的自定義begin(),并end()在的std ::命名空間。


這是一個非常簡單的示例解決方案:


// -------------------------------------------------------------------

// --- Reversed iterable


template <typename T>

struct reversion_wrapper { T& iterable; };


template <typename T>

auto begin (reversion_wrapper<T> w) { return std::rbegin(w.iterable); }


template <typename T>

auto end (reversion_wrapper<T> w) { return std::rend(w.iterable); }


template <typename T>

reversion_wrapper<T> reverse (T&& iterable) { return { iterable }; }

例如,這就像一個咒語一樣工作:


template <typename T>

void print_iterable (std::ostream& out, const T& iterable)

{

    for (auto&& element: iterable)

        out << element << ',';

    out << '\n';

}


int main (int, char**)

{

    using namespace std;


    // on prvalues

    print_iterable(cout, reverse(initializer_list<int> { 1, 2, 3, 4, }));


    // on const lvalue references

    const list<int> ints_list { 1, 2, 3, 4, };

    for (auto&& el: reverse(ints_list))

        cout << el << ',';

    cout << '\n';


    // on mutable lvalue references

    vector<int> ints_vec { 0, 0, 0, 0, };

    size_t i = 0;

    for (int& el: reverse(ints_vec))

        el += i++;

    print_iterable(cout, ints_vec);

    print_iterable(cout, reverse(ints_vec));


    return 0;

}

按預期打印


4,3,2,1,

4,3,2,1,

3,2,1,0,

0,1,2,3,

注意 std::rbegin(),std::rend()和std::make_reverse_iterator()尚未在GCC-4.9中實現。我根據標準編寫了這些示例,但是它們無法在穩定的g ++中編譯。但是,為這三個功能添加臨時存根非常容易。這是一個示例實現,肯定還不完整,但在大多數情況下效果很好:


// --------------------------------------------------

template <typename I>

reverse_iterator<I> make_reverse_iterator (I i)

{

    return std::reverse_iterator<I> { i };

}


// --------------------------------------------------

template <typename T>

auto rbegin (T& iterable)

{

    return make_reverse_iterator(iterable.end());

}


template <typename T>

auto rend (T& iterable)

{

    return make_reverse_iterator(iterable.begin());

}


// const container variants


template <typename T>

auto rbegin (const T& iterable)

{

    return make_reverse_iterator(iterable.end());

}


template <typename T>

auto rend (const T& iterable)

{

    return make_reverse_iterator(iterable.begin());

}


查看完整回答
反對 回復 2019-10-15
?
子衿沉夜

TA貢獻1828條經驗 獲得超3個贊

這應該可以在C ++ 11中正常工作而無需增強:


namespace std {

template<class T>

T begin(std::pair<T, T> p)

{

    return p.first;

}

template<class T>

T end(std::pair<T, T> p)

{

    return p.second;

}

}


template<class Iterator>

std::reverse_iterator<Iterator> make_reverse_iterator(Iterator it)

{

    return std::reverse_iterator<Iterator>(it);

}


template<class Range>

std::pair<std::reverse_iterator<decltype(begin(std::declval<Range>()))>, std::reverse_iterator<decltype(begin(std::declval<Range>()))>> make_reverse_range(Range&& r)

{

    return std::make_pair(make_reverse_iterator(begin(r)), make_reverse_iterator(end(r)));

}


for(auto x: make_reverse_range(r))

{

    ...

}


查看完整回答
反對 回復 2019-10-15
  • 3 回答
  • 0 關注
  • 1939 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號