拉丁的传说
实际上,在C ++ 14中,只需几行代码即可完成。这在思想上与@Paul的解决方案非常相似。由于C ++ 11中缺少某些内容,因此该解决方案有点不必要地过大(加上在std气味中定义)。感谢C ++ 14,我们可以使它更具可读性。关键的观察结果是,基于范围的for循环通过依赖begin()和end()来获取范围的迭代器而工作。由于ADL,一个甚至不需要定义自己的自定义begin(),并end()在的std ::命名空间。这是一个非常简单的示例解决方案:// -------------------------------------------------------------------// --- Reversed iterabletemplate <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 variantstemplate <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());}