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;})
Так что теперь ясно, что вы работаете над элементом вектор, а не сам вектор.
Следующий стандарт C++, C++ 0X (где X обозначает, надо надеяться, 9) добавит возможность измениться от перспективы итератора до контейнерной перспективы. Вы сможете сделать, например.
станд.:: вид (my_vec);
Если бы Вы наклоняетесь, ожидают этого, я рекомендовал бы Вам посмотреть на: Повышение. Диапазон
И если бы Вы действительно интересуетесь итераторами/диапазонами, я рекомендовал бы для чтения "итераторов Andrei пойти"
Многие встретились с этой неприятностью. Хотя понятие итератора является исключительно общим, оно испытывает недостаток в некотором удобстве использования.
Введите понятие 'диапазона'. Это должно быть предпочтено для предотвращения любого дублирования кода. Таким образом, при обнаружении с .begin () и .end () пары на всем протяжении кода это - хорошая практика для создания слоя, промежуточного 'получение итератора' и фактические алгоритмы.
Ссылки:
...
#define ALL(x) (x).begin(), (x).end()
sort(ALL(vec));
Во-первых, я не думаю, что это - большая проблема. В целом я действительно не забочусь о вводе еще нескольких символов. удобочитаемость более важна, и я думаю, начинают/заканчивают, совершенно читаемо.
Более короткие контейнерные имена могут помочь хотя (con.begin () легче ввести, чем container.begin ()),
И раздавание итераторов вместо самого контейнера означает, что Вы не должны звонить, начинают/заканчивают несколько раз в любом случае.
Это не действительно что-то, что беспокоит меня.
Если бы это стало действительно плохим, то я, вероятно, создал бы набор шаблонов для моих обычно используемых алгоритмов в новом пространстве имен:
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()!
C++ 11 обратился к этому незначительному раздражению в языке.
boost :: range_ex решит эту проблему до c ++ 0x.
И написать несколько несложно Оберните себя тем временем.
Эта красивая презентация [PDF] о возможном будущем решении этой проблемы была недавно связана с Reddit. обсуждается, как полностью заменить итераторы концепцией диапазона.