Funkcja remove_if ( forward_list )

0

Witam.
Mam napisaną klasę Osoba, która posiada imie i nazwisko. Następnie utworzyłem listę jednokierunkową za pomocą forward_list.

#include <iostream>
#include <forward_list>
#include <cstdlib>
#include <ctime>
#include <conio.h>

using namespace std;

class Osoba{
    private:
        string imie;
        string nazwisko;
    public:
        Osoba(){
            cout<<"Podaj imie osoby: ";
            cin>>imie;
            cout<<"Podaj nazwisko osoby: ";
            cin>>nazwisko;
        }

        string getImie(){
            return imie;
        }

        string getNazwisko(){
            return nazwisko;
        }      
};
int main()
{
    forward_list<Osoba> lista_osob; 

    // TUTAJ DODAŁEM DO LISY KILKA OSOB ( push_front ), TERAZ CHCE USUNĄĆ OSOBĘ/Y, KTÓRA NAZYWA SIĘ JAN KOWALSKI
    // Próbowałem użyć wbudowanej metody remove_if, ale przy kompilacji wyskakują błędy. 
    //Chodzi tutaj o to co siedzi w nawiasach remove_if, ale nie wiem jak odnieść się do imienia lub nazwiska, tak aby porównywał imię i nazwisko każdej osoby z listy

    lista_osob.remove_if(lista_osob.getImie()=="Jan" && lista_osob.getNazwisko()=="Kowalski");

   return 0;
}

Problem tkwi w funkcji remove_if.

4
  1. Dokumentacja nie boli: http://en.cppreference.com/w/cpp/container/forward_list/remove
  2. Problemy z podstawami - Newbie
  3. Dlaczego używasz forward_list? To raczej mało przydatny kontener, jakie masz argumenty przeciwko wektorowi (albo chociażby liście dwukierunkowej)?
0
  1. Sprawdzałem dokumentację. Gdybym zrozumiał, to bym nie napisał wątku.
  2. Jeżeli chodzi o kontenery to dopiero je poznaję, nie miałem nigdy styczności z wektorami w programowaniu.
    W tym przypadku to chyba lista kierunkowa wystarczy, czy się mylę?
4

vector to po prostu dynamiczna tablica. Masz random access, w znaczącej większości przypadków lepszą wydajność i zdecydowanie wygodniejszą obsługę. forward_list nie ma nic z tego, jest trudniejsza w użyciu i generalnie ma zastosowanie tylko w miejscach z bardzo ograniczoną ilością pamięci.

W podlinkowanej dokumentacji masz przykład z predykatem. Chcesz zrobić dokładnie to samo, tylko na typie danych Osoba. Zakładam, że lambdy znasz.

0

Nie znam. Znam tylko podstawy jak tablica statyczne i dynamiczne, listy jednokierunkowe i dwukierunkowe oraz podstawy programowania obiektowego ( konstruktory, destruktory, dziedziczenie itp. ).

Pisząc listę samemu wiem jak to zrobić. Należałoby przejść przez listę i w pętli sprawdzić czy warunki są spełnione, usunąć element listy i "podpiąć" wskaźnik poprzedniego elementu na następny po usuniętym. Tylko to sporo roboty, zapewne dlatego wymyślono szybszy sposób.

l.remove_if([](int n){ return n > 10; }); // remove all elements greater than 10 

Nie rozumiem tego zapisu, dokładniej to ([](int n)

2
[](int n){ return n > 10; } 
0

Dla Jana Kowalskiego działa:

lista_osob.remove_if([](Osoba o){ return (o.getImie()=="Jan" && o.getNazwisko()=="Kowalski"); }); 

Teraz chciałbym, aby usuwał osobę wczytaną z klawiatury. Pobieram imie i nazwisko

string imie, nazwisko;
cin>>imie>>nazwisko;
lista_osob.remove_if([](Osoba o, string i, string n){ return (o.getImie()==i && o.getNazwisko()==n); }(TUTAJ, imie, nazwisko)); 

Pytanie jest takie, co należy wpisać w nawiasie po returnie, zmienna TUTAJ?

1
string imie, nazwisko;
cin>>imie>>nazwisko;
lista_osob.remove_if([&](Osoba o){ return (o.getImie()==imie && o.getNazwisko()== nazwisko); });  
1

Taki mało rozgarnięty przykład. Może się przyda:

struct Foo
{
    string name, lname;
};

string lname, name;

void ShowIf(const Foo& f)
{
    if (f.name == name && f.lname == lname)
        cout << f.name << ' ' << f.lname;
}

int main()
{
    vector<Foo> v{ { "jan", "kowalski" }, { "tedi", "jakis" } };    
    cin >> name >> lname;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    for_each(v.cbegin(), v.cend(), // wypisz jeśli dane zgodne
        [&](const Foo f){if (f.name == name && f.lname == lname)
        cout << f.name << ' ' << f.lname << endl; });

    for_each(v.cbegin(), v.cend(), ShowIf); // to samo z użyciem zewnętrznej funkcji

    std::cin.get();
    return 0;
} 

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0