Как использовать идиому удаления-стирания для удаления пустых векторов в векторе?

У меня возникли проблемы с удалением пустого вектора в векторе с использованием идиомы удаления-стирания, такой как вектор. Как я могу применить это к:

vector<vector<Point> > contours; // want to remove contours.at(i).empty()
contours.erase(remove(contours.begin(), contours.end(), ??? ),contours.end());

person aagaard    schedule 13.12.2011    source источник


Ответы (3)


Ты пытался:

contours.erase(remove(contours.begin(), contours.end(), vector<Point>()), contours.end());
person moswald    schedule 13.12.2011
comment
Действительно: это может быть излишним в том смысле, что компилятор может выдать больше кода, чем это строго необходимо, но это лаконично. - person Steve Jessop; 13.12.2011
comment
Если предположить, что сравнение дешевое, как и должно быть, это отличное решение! - person 111111; 13.12.2011
comment
Сравнение должно быть дешевым, так как первое, что делает vector::operator==, — это сравнение size() для обеих сторон. - person Blastfurnace; 13.12.2011
comment
Спасибо, это то, что мне было нужно! - person aagaard; 13.12.2011
comment
Blastfurnace считал, что так и должно быть. - person 111111; 13.12.2011

Используйте remove_if, который принимает предикат.

contours.erase(
    std::remove_if(
         contours.begin(), contours.end(),
         [](const vector<Point>& v) { return v.empty(); }
         // or a functor/plain function/Boost.Lambda expression
    ), contours.end()
);
person Cat Plus Plus    schedule 13.12.2011
comment
Это работает! Хорошее предложение, я на самом деле рассматривал его с помощью лямбда-выражений, так что спасибо за ваше предложение. - person aagaard; 13.12.2011
comment
Хотя всем нравятся лямбда-выражения, я нахожу std::mem_fn(&std::vector<Point>::empty) еще более кратким и ясным. - person Christian Rau; 14.01.2013

используйте remove_if.

C++11

contours.erase(
    std::remove_if(contours.begin(), contours.end(), 
        [&](const Vector<Point>& vp){
            return vp.empty();
        }),
        contours.end());

C++03

struct is_empty
{
    bool operator()(const Vector<Point>& vp) constt;
    {
        return vp.empty();
    }
}


contours.erase(
         std::remove_if(contours.begin(), contours.end(), 
         is_empty,
         contours.end());
person 111111    schedule 13.12.2011
comment
Вам не нужен пользовательский функтор в C++03, достаточно простого std::mem_fun_ref(&std::vector<Point>::empty). - person Christian Rau; 14.12.2012
comment
То же самое верно и для C++11, только с std::mem_fn, где это также более лаконично и концептуально чище, чем лямбда, но хорошо, это, возможно, скорее вопрос вкуса. Но для C++03 не использовать его скудные функциональные возможности, когда они, наконец, обретают смысл, — это немного преступление;) - person Christian Rau; 14.12.2012
comment
Кстати, внутри вызова функции должно быть const вместо constt и is_empty() вместо is_empty. - person Christian Rau; 14.12.2012