• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Operator zamiast predykatu w algorytmach STLa - problem

Object Storage Arubacloud
0 głosów
358 wizyt
pytanie zadane 3 października 2015 w C i C++ przez broda Początkujący (380 p.)
edycja 4 października 2015 przez Patrycjerz
//uczen.h

    Uczen ( string imie, string nazwisko, string telefon )
        : imie ( imie ), nazwisko ( nazwisko ), telefon ( telefon )
    {}

    bool operator== ( const Uczen& rhs ) {
        return rhs.imie == imie && rhs.nazwisko == nazwisko;
    }

//dziennik.cpp - Dziennik - klasa, ktora przetrzymuje uczniow w vectorze
//funkcja Usun usuwa ucznia po imieniu i nazwisku

void Dziennik::Usun( string a, string b)
{
    Uczen os(a,b,"11111"); //tutaj tworze tak bardzo naiwnie, jest jakiś inny sposob, bez wpisywania telefonu?
    Uczen& ref=os;

    remove_if(wpisy.begin(), wpisy.end(), ref.operator==);
}

Dostaję taki bląd:
Error    1    error C3867: 'Uczen::operator ==': function call missing argument list; use '&Uczen::operator ==' to create a pointer to member

Ale przecież robię ref.operator==, więc o co chodzi?

2 odpowiedzi

+1 głos
odpowiedź 4 października 2015 przez Radfler VIP (101,030 p.)
wybrane 4 października 2015 przez broda
 
Najlepsza

Spróbuję Ci pomóc:

Po pierwsze funkcja std::remove_if przyjmuje jednoargumentowy predykat. Z tego co się orientuję operator== jest operatorem dwuargumentowym. Po drugie taki zapis:

ref.operator==

nie jest w C++ prawidłowy. Rozumiem, że chciałeś pobrać adres tej funkcji, jednak robi się to trochę inaczej:

&Uczen::operator==

Pobieramy tz. wskaźnik na członka (pointer to member function: http://en.cppreference.com/w/cpp/language/pointer). W tym przypadku użycie tego i tak nie jest prawidłowe.

Można to naprawić w taki sposób, używając np. std::bind lub lambdy:

remove_if(wpisy.begin(), wpisy.end(), std::bind(&Uczen::operator==, ref, std::placeholders::_1));
remove_if(wpisy.begin(), wpisy.end(), [&](const Uczen& other) { return ref == other; });

Nie mam możliwości przetestowania kodu, ale powinno działać :)

komentarz 4 października 2015 przez draghan VIP (106,230 p.)

Wersja z lambdą jest elegancka. :) Ode mnie yes - sam nie miałem sensownego pomysłu jak to sklecić w działąjącą całość. frown

komentarz 4 października 2015 przez broda Początkujący (380 p.)
O czym informuje referencja w [] - znaku, rozpoczynającym lambdę?
komentarz 4 października 2015 przez notabigthreat Mądrala (7,060 p.)
"lambda capture" - dzięki temu można używać `ref`, w dodatku pracuje się na oryginale (dlatego znak '&')
komentarz 4 października 2015 przez Radfler VIP (101,030 p.)

Jest to tzw. capture list (http://en.cppreference.com/w/cpp/language/lambda). W tym przypadku znaczek referencji informuje, że "przechwytujemy" wszystkie zmienne automatyczne (nie statyczne, nie globalne) przez referencję. Tu akurat jest nam potrzebne, aby korzystać ze zmiennej ref wewnątrz lambdy ;)

https://forum.pasja-informatyki.pl/21219/funkcja-lambda-capture-list

komentarz 4 października 2015 przez broda Początkujący (380 p.)
Czy remove_if powinno automatycznie zmniejszyć wektor o jeden przy każdym usunięciu?
komentarz 4 października 2015 przez notabigthreat Mądrala (7,060 p.)
remove_if nie usuwa, tylko przesuwa spełniające warunek elementy na koniec i zwraca iterator o jeden dalej niż ostatni nie przesunięty element.
komentarz 4 października 2015 przez Radfler VIP (101,030 p.)

Nie, usuwane elementy zostaną przeniesione na koniec zakresu <begin, end). Jednak elementy można i tak w łatwy sposób usunąć:

vector.erase(std::remove_if(vector.begin(), vector.end(), predicate), vector.end());

Taki zapis usunie niechciane elementy :)

http://en.cppreference.com/w/cpp/algorithm/remove

komentarz 4 października 2015 przez broda Początkujący (380 p.)
O to mi chodziło.
Bo przedtem było tak:
przed usuwaniem: ABCB,
a po usuwaniu: ABCC

Dlaczego C został zduplikowany?
komentarz 4 października 2015 przez Radfler VIP (101,030 p.)
Kwestia działania algorytmu ;) W tym wypadku powodów może być dużo, ale postaram się poszukać dlaczego.
0 głosów
odpowiedź 4 października 2015 przez draghan VIP (106,230 p.)
edycja 4 października 2015 przez draghan

Czy algorytm remove_if() nie wymaga predykatu jednoparametrowego? Jak rozumiem, bool operator== ( const Uczen& rhs ) jest metodą klasy Uczen?

Podobne pytania

0 głosów
2 odpowiedzi 277 wizyt
pytanie zadane 23 listopada 2019 w C i C++ przez niezalogowany
0 głosów
2 odpowiedzi 562 wizyt
pytanie zadane 22 marca 2020 w C i C++ przez wall7489 Obywatel (1,250 p.)
0 głosów
1 odpowiedź 164 wizyt
pytanie zadane 19 czerwca 2017 w C i C++ przez Rivit Nowicjusz (200 p.)

92,576 zapytań

141,426 odpowiedzi

319,650 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...