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

Jak zamienić ten kod na działający w standardzie c++ 0x

Object Storage Arubacloud
0 głosów
354 wizyt
pytanie zadane 26 kwietnia 2017 w C i C++ przez konrad99 Gaduła (4,090 p.)
bool czy_zawiera(string message,string co_ma_zawierac)
{
    bool odp =std::all_of(message.cbegin(),message.cend(),[&co_ma_zawierac](char c)
{return co_ma_zawierac.find(c)!=std::string::npos; }

                          );
                          return odp;
}

2 odpowiedzi

0 głosów
odpowiedź 27 kwietnia 2017 przez criss Mędrzec (172,590 p.)
wybrane 9 maja 2017 przez konrad99
 
Najlepsza

Przede wszystkim zmień nazwe tematu jeśli to możliwe (nie jestem pewien), skoro jednak chodzi ci o co innego.

Co do twojego pytania, to:

Skoro Borland nie obsługuje c++11, to musisz pozbyć się wszystkiego co zostało wprowadzone w tym standardzie. Lambda na pewno została wprowadzona w c++11, std::all_of, z tego co widze w dokumentacji, też. Działanie std::all_of jest na tyle proste, że najłatwiej będzie po prostu napisać to samemu:

bool czy_zawiera(const string & message, const string & co_ma_zawierac)
{
   for(int i = 0; i < message.size(); i++)
      if(co_ma_zawierac.find(message[i]) == std::string::npos)
         return false;
   return true;
}

(dodatkowo zadeklarowalem argumenty jako const referencje)

0 głosów
odpowiedź 27 kwietnia 2017 przez draghan VIP (106,230 p.)

Ciekawy miks stylów: tu trochę po polsku, tam trochę po angielsku, gdzieś jawne specyfikowanie przynależności identyfikatorów, innym razem nie. :)

Technicznie rzecz biorąc, Twój kod działa w "standardzie" 0x (tak naprawdę to nieoficjalna nazwa standardu C++11 sprzed jego wprowadzenia).

Zaś co do poprawności jego działania... Jeśli ma on sprawdzać, czy w łańcuchu message zawarty jest łańcuch co_ma_zawierac, to nie działa on poprawnie.

A takie rozwiązanie Cię nie satysfakcjonuje?

bool czy_zawiera(const std::string &message, const std::string &co_ma_zawierac)
{
    return message.find(co_ma_zawierac) != std::string::npos;
}

 

komentarz 27 kwietnia 2017 przez niezalogowany
"Ciekawy miks stylów: tu trochę po polsku, tam trochę po angielsku" - człowiek renesansu, wielokulturowy.
komentarz 27 kwietnia 2017 przez konrad99 Gaduła (4,090 p.)
Chodzi mi o to aby w tekście message były tylko litery co_ma_zawierac i gdyby tak nie było funkcja by fałsz zgłaszała standard źle wpisałem chodziło mi o to aby ten kod działał w Borland c++ a nie działa co jest raczej związane z tym że występują tam elementy c++11
komentarz 27 kwietnia 2017 przez criss Mędrzec (172,590 p.)
@draghan, twoje rozwiązanie sprawdza czyli message zawiera co_ma_zawierac jako cały ciąg znaków. Autor chciał sprawdzać, czy message składa się tylko ze znaków z których składa się co_ma_zawierac.
komentarz 27 kwietnia 2017 przez draghan VIP (106,230 p.)

@draghan, twoje rozwiązanie sprawdza czyli message zawiera co_ma_zawierac jako cały ciąg znaków.  Autor chciał sprawdzać, czy message składa się tylko ze znaków z których składa się co_ma_zawierac.

Jestem świadom, co robi kod, który napisałem. ;) Fajnie, że przy zadawaniu pytania konrad99 jasno określił, o co chodzi... :)

 

komentarz 27 kwietnia 2017 przez criss Mędrzec (172,590 p.)
No wzorowo zadane pytanie to nie jest :D Wiem, że jesteś świadom :) Chciałem, tylko pokazać różnice.
komentarz 27 kwietnia 2017 przez draghan VIP (106,230 p.)

Abstrahując od tego, że można to zrobić bardzo prosto (patrz rozwiązanie Crissa), możemy po kolei rozprawiać się z elementami, które doszły w "jedenastce".

Najpierw oczywistość: pozbywamy się lambdy. W tym miejscu można byłoby wstawić funkcję, która zwraca bool, przyjmując char... Tylko brakuje nam wartości co_ma_zawierac, która jest do lambdy wciągana przez referencję. Bez dodania do funkcji kolejnego argumentu nie uda nam się tego zrealizować, zaś jego dodanie spowoduje niemożność przekazania adresu tej funkcji do algorytmu all_of.

Rozwiązaniem jest więc obiekt funkcyjny, który będzie posiadał pole zawierające wartość co_ma_zawierac i oczywiście operator wywołania o pasującym nagłówku. Operator ten będzie robił dokładnie to samo, co w oryginale robiła lambda.

class LambdaSubstitute
{
public:
    LambdaSubstitute(const std::string &co_ma_zawierac)
            :co_ma_zawierac(co_ma_zawierac)
    {
    }

    bool operator()(char c) const
    {
        return co_ma_zawierac.find(c)!=std::string::npos;
    }
private:
    std::string co_ma_zawierac;
};

Teraz jednak... nie mamy implementacji std::all_of. Jest ona dość prosta. Jeśli w zbiorze nie znajdziemy elementu, który nie spełnia warunku, to znaczy że wszystkie elementy spełniają warunek.

No to napiszmy:

template<class Iterator, class Predicate>
bool all_of(Iterator first, Iterator last, Predicate p)
{
    return std::find_if(first, last, std::not1(p)) == last;
}

Żeby można było używać do zanegowania predykatu std::not1, predykat musi dziedziczyć po szablonie std::unary_function, dodajemy więc rodzica wraz z odpowiednimi argumentami szablonowymi (odpowiadającymi typowi operatora wywołania):

class LambdaSubstitute: public std::unary_function<char, bool>
{
    // ...
};

No i oczywiście sama funkcja wygląda teraz tak (usunięte stałe iteratory):

bool czy_zawiera(const std::string &message, const std::string &co_ma_zawierac)
{
    LambdaSubstitute predicate(co_ma_zawierac);
    return all_of(message.begin(),message.end(), predicate);
}

W tym konkretnym wypadku lepiej zastosować rozwiązanie Crissa, jednak może komuś na przyszłość się przyda. :)

Podobne pytania

0 głosów
1 odpowiedź 108 wizyt
0 głosów
2 odpowiedzi 227 wizyt
0 głosów
1 odpowiedź 628 wizyt
pytanie zadane 8 grudnia 2015 w C i C++ przez mikra25 Użytkownik (580 p.)

92,566 zapytań

141,420 odpowiedzi

319,606 komentarzy

61,952 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!

...