начните (), конец () раздражение в алгоритмах STL

find_if собирается передать элементы вектора в вашу лямбду. Это означает, что вам нужно

std::find_if(V.begin(), V.end(), [&Name](auto const& V) {return Name == V->info.name;})

, чтобы V в теле лямбда-элемента было элементом вектора, а не самого вектора.


В идеале вы бы дали ему другое имя, чем V, поэтому вы держите вектор и локальные переменные отдельно, как

std::find_if(V.begin(), V.end(), [&Name](auto const& element) {return Name == elememt->info.name;})

Так что теперь ясно, что вы работаете над элементом вектор, а не сам вектор.

16
задан Schildmeijer 9 May 2009 в 20:42
поделиться

8 ответов

Следующий стандарт C++, C++ 0X (где X обозначает, надо надеяться, 9) добавит возможность измениться от перспективы итератора до контейнерной перспективы. Вы сможете сделать, например.

станд.:: вид (my_vec);

Если бы Вы наклоняетесь, ожидают этого, я рекомендовал бы Вам посмотреть на: Повышение. Диапазон

И если бы Вы действительно интересуетесь итераторами/диапазонами, я рекомендовал бы для чтения "итераторов Andrei пойти"

28
ответ дан 30 November 2019 в 15:12
поделиться

Многие встретились с этой неприятностью. Хотя понятие итератора является исключительно общим, оно испытывает недостаток в некотором удобстве использования.

Введите понятие 'диапазона'. Это должно быть предпочтено для предотвращения любого дублирования кода. Таким образом, при обнаружении с .begin () и .end () пары на всем протяжении кода это - хорошая практика для создания слоя, промежуточного 'получение итератора' и фактические алгоритмы.

Ссылки:

...

19
ответ дан 30 November 2019 в 15:12
поделиться
#define ALL(x) (x).begin(), (x).end()

sort(ALL(vec));
7
ответ дан 30 November 2019 в 15:12
поделиться

Во-первых, я не думаю, что это - большая проблема. В целом я действительно не забочусь о вводе еще нескольких символов. удобочитаемость более важна, и я думаю, начинают/заканчивают, совершенно читаемо.

Более короткие контейнерные имена могут помочь хотя (con.begin () легче ввести, чем container.begin ()),

И раздавание итераторов вместо самого контейнера означает, что Вы не должны звонить, начинают/заканчивают несколько раз в любом случае.

Это не действительно что-то, что беспокоит меня.

3
ответ дан 30 November 2019 в 15:12
поделиться

Если бы это стало действительно плохим, то я, вероятно, создал бы набор шаблонов для моих обычно используемых алгоритмов в новом пространстве имен:

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()!
3
ответ дан 30 November 2019 в 15:12
поделиться

C++ 11 обратился к этому незначительному раздражению в языке.

3
ответ дан 30 November 2019 в 15:12
поделиться

boost :: range_ex решит эту проблему до c ++ 0x.

И написать несколько несложно Оберните себя тем временем.

1
ответ дан 30 November 2019 в 15:12
поделиться

Эта красивая презентация [PDF] о возможном будущем решении этой проблемы была недавно связана с Reddit. обсуждается, как полностью заменить итераторы концепцией диапазона.

3
ответ дан 30 November 2019 в 15:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: