2016-11-11 56 views
0

我希望能夠以簡單的for (const auto& item : collection)風格以相反的順序迭代集合(我只會在矢量上做這件事情,如果這很重要),我發現這個答案完美:https://stackoverflow.com/a/28139075/2195721。但後來我想是能夠向前或向後遍歷,所以我修改了代碼如下所示:製作可互換的向前/向後的範圍迭代器

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

template <typename T> 
struct reversable_wrapper { 
    T& iterable; 
    bool reverse; 

    reversable_wrapper(T&& iterable) : reversable_wrapper(iterable, true) {}; 
    reversable_wrapper(T&& iterable, bool reverse) : iterable(iterable), reverse(reverse) {}; 
}; 

template <typename T> 
auto std::begin (reversable_wrapper<T> w) 
{ 
    if (w.reverse) return std::rbegin(w.iterable); 
    else return std::begin(w.iterable); 
} 

template <typename T> 
auto std::end (reversable_wrapper<T> w) 
{ 
    if (w.reverse) return std::rend(w.iterable); 
    else return std::end(w.iterable); 
} 

template <typename T> 
reversable_wrapper<T> reverse (T&& iterable) { return reversable_wrapper<T>(iterable); } 

template <typename T> 
reversable_wrapper<T> forward (T&& iterable) { return reversable_wrapper<T>(iterable, false); } 

int main() 
{ 
    std::vector<int> vec = {1,2,3}; 
    for (const auto& i : reverse(vec)) std::cout<<i<<std::endl; 
    return 0; 
} 

基本上,我想達到爲for (const auto& item : cond ? forward(coll) : reverse(coll))。然而,這個代碼給我下面的錯誤:

> $ g++ -std=c++14 iterators.cpp -o iterators 
iterators.cpp: In instantiation of ‘auto std::begin(reversable_wrapper<T>) [with T = std::vector<int>&]’: 
iterators.cpp:37:37: required from here 
iterators.cpp:18:38: error: inconsistent deduction for ‘auto’: ‘std::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >’ and then ‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ 
    else return std::begin(w.iterable); 
            ^
iterators.cpp: In instantiation of ‘auto std::end(reversable_wrapper<T>) [with T = std::vector<int>&]’: 
iterators.cpp:37:37: required from here 
iterators.cpp:25:36: error: inconsistent deduction for ‘auto’: ‘std::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >’ and then ‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ 
    else return std::end(w.iterable); 

我想不通,我可以給其簽名std::beginstd::end克服這一點,如果這是不可能的。

我使用的是g ++ 5.4.0。

回答

0

你的問題是,你正試圖從你的函數返回std::vector::iteratorstd::vector::reverse_iterator之一。可悲的是,這些都是無關的類型。

我認爲你唯一的機會是寫一個reversible_iterator_wrapper它擁有這兩種類型,並將其參數轉發到正確的。這將是乏味的。最簡單的(但不是最有效的)選項可能涉及虛擬功能!