알고리즘 - std find c++




STL 알고리즘의 begin(), end() 성가심 (6)

나는 STL 알고리즘을 좋아하고 일반적인 루프보다는 사용 알고리즘을 선호한다.
거의 모든 STL 알고리즘은 일반적으로 다음과 같이 사용됩니다.

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

container.begin(), container.end() - 내 프로젝트에서 가장 인기있는 단어 쌍 중 하나입니다.

아무도 같은 문제가 있습니까?
너희들이 어떻게이 문제를 해결 하나?
이 중복을 피하기 위해 당신은 무엇을 제안 할 수 있습니까? 솔루션을위한 몇 가지 방법을 볼 수 있지만, 모두 다른 제한 사항 (매크로 사용법, 일반 포인터와 호환되지 않음 등)이 있습니다.


boost :: range_ex는 c ++ 0x 전에 이것을 해결할 것입니다.

그 동안에는 몇 개의 래퍼를 쓰는 것이 어렵지 않습니다.


다음 C ++ 표준 인 C ++ 0X (X는 잘하면 9 임)는 반복자 관점에서 컨테이너 관점으로 변경할 가능성을 추가합니다. 예를 들어 할 수 있습니다.

std :: sort (my_vec);

이 일을 기다릴 수 없다면 다음과 같이 보도록 권합니다. Boost.Range

그리고 당신이 정말로 iterators / ranges에 관심이 있다면 Andrei의 " iterators should go "를 읽으라고 권하고 싶습니다.


첫째로, 나는 그것이 큰 문제라고 생각하지 않는다. 일반적으로 나는 더 많은 문자를 입력하는 것에 정말로 신경 쓰지 않는다. 가독성이 더 중요하며 begin / end가 완벽하게 읽을 수 있다고 생각합니다.

짧은 컨테이너 이름도 도움이 될 수 있습니다 (con.begin ()은 container.begin ()보다 더 쉽게 입력 할 수 있습니다)

컨테이너 자체 대신에 반복자를 전달하면 어떤 경우에도 begin / end를 두 번 이상 호출 할 필요가 없다는 것을 의미합니다.

그것은 나를 귀찮게하는 것이 아닙니다.


C++11 은이 언어에서이 사소한 불편 함을 해결했습니다.


정말 좋지 않다면 아마도 가장 일반적으로 사용되는 알고리즘을위한 새로운 네임 스페이스 템플릿을 만들 것입니다.

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()!

#define ALL(x) (x).begin(), (x).end()

sort(ALL(vec));






stl