代码之家  ›  专栏  ›  技术社区  ›  bayda

STL算法中的begin(),end()烦恼

  •  15
  • bayda  · 技术社区  · 16 年前

    我喜欢STL算法,更喜欢使用算法而不是通常的循环。

    std::algorithm_name( container.begin(), container.end(), ..... )  
    

    container.begin(), container.end()

    有人有同样的问题吗?
    你们怎么解决这个问题?

    8 回复  |  直到 16 年前
        1
  •  28
  •   Schildmeijer    16 年前

    下一个C++标准C++(9),将增加从迭代器透视图到容器透视图的可能性。你将能做某事。

    如果你等不及了,我建议你看看: Boost.Range

    如果你真的对迭代器/范围感兴趣,我建议你阅读Andrei的“ iterators must go "

        2
  •  19
  •   Ferruccio    16 年前

    输入“范围”概念。最好避免 任何 代码重复。因此,如果在代码中遇到.begin()和.end()对,最好在“迭代器获取”和实际算法之间创建一个层。

    参考资料:

    ...

        3
  •  7
  •   oberon oberon    16 年前
    #define ALL(x) (x).begin(), (x).end()
    
    sort(ALL(vec));
    
        4
  •  3
  •   Stack Overflow is garbage    16 年前

    首先,我认为这不是什么大问题。一般来说,我并不真的在乎多输入几个字符。可读性更重要,我认为begin/end是完全可读的。

    传递迭代器而不是容器本身意味着您在任何情况下都不必多次调用begin/end。

        5
  •  3
  •   j_random_hacker    16 年前

    真糟糕 ,我可能会在新名称空间中为我最常用的算法创建一组模板:

    namespace my_ranged_algorithms {
        // Metafunction for extracting an appropriate iterator from
        // the container type
        template <typename T>
        struct get_iterator_type_for;
    
        // For vectors
        template <typename T>
        struct get_iterator_type_for<std::vector<T> > {
            typedef typename std::vector<T>::iterator type;
        };
    
        template <typename T>
        struct get_iterator_type_for<std::vector<T> const> {
            typedef typename std::vector<T>::const_iterator type;
        };
    
        // For C arrays
        template <typename T, size_t N>
        struct get_iterator_type_for<T(&)[N]> {
            typedef T* type;
        };
    
        // Generic begin() and end() wrappers
    
        // For all standard containers        
        template <typename Cont>
        typename get_iterator_type_for<Cont>::type begin(Cont& c) {
            return c.begin();
        }
    
        template <typename Cont>
        typename get_iterator_type_for<Cont>::type end(Cont& c) {
            return c.end();
        }
    
        // For C arrays
        template <typename T, size_t N>
        typename get_iterator_type_for<T (&)[N]>::type begin(T (&c)[N]) {
            return c;
        }
    
        template <typename T, size_t N>
        typename get_iterator_type_for<T (&)[N]>::type end(T (&c)[N]) {
            return c + N;
        }
    
        // Finally, the actual algorithm wrappers
    
        // copy
        template <typename Cont, typename OutIter>
        OutIter copy(Cont& from, OutIter to) {
            return std::copy(begin(from), end(from), to);
        }
    
        // remove
        template <typename Cont, typename T>
        typename get_iterator_type_for<Cont>::type remove(Cont& from, T x) {
            return std::remove(begin(from), end(from), x);
        }
    
        // etc.
    };
    

    然后这样称呼他们:

    vector<int> a, b;
    using namespace my_ranged_algorithms;
    
    copy(a, back_inserter(b));
    b.erase(remove(b, 42), b.end()); // Remember to call erase() after remove()!
    
        6
  •  3
  •   shoosh    16 年前

    This nice presentation [PDF]reddit最近链接了关于未来可能的解决方案。它讨论了如何用范围概念完全替换迭代器。

        7
  •  3
  •   Camille Goudeseune 123iamking    9 年前
        8
  •  1
  •   Macke    16 年前

    boost::range_ex将在c++0x之前解决此问题。

    同时,自己编写一些包装也不难。