#include <iostream> #include <fstream> #include <functional> #include <algorithm> #include <list> #include <vector> #include <map> #include <iterator> #include <string> #include <cstring> using namespace std; using std::placeholders::_1; // do przykładu *8* //using std::placeholders::_2; obiekty funkcyjne - funktory int main() { // *1* ------------------------------------ plus<float> p; negate<double> n; greater<char> g; logical_and<int> a; cout << p(3.14, 4.375) << ' ' << n(-1.23) << ' ' << g('z', 'a') << ' ' << a(1, 0) << endl; // 7.515 1.23 1 0
obiekty funkcyjne, wyrażenie lambda // *2* ------------------------------------ przed programem struct mniej_niz { mniej_niz(int x_) : x(x_) { bool operator () (int y) const { return y < x; private: int x; // *2* ------------------------------------ w programie list<int> l = { 11, 2, 13, 1, 7, 9, -1 l.sort( greater<int>() ); ostream_iterator<int> out(cout, " "); copy(l.begin(), l.end(), out); // 13 11 9 7 2 1-1 //l.remove_if(mniej_niz(7)); //l.remove_if( []( int i ){ return i<7; ); int minval = 0, maxval = 7; l.remove_if( [ minval, maxval ]( int i ){ cout << "min max "<<minval<<"," <<maxval<<","<<i<<endl; return i>minval && i<maxval ; ); copy(l.begin(), l.end(), out); // 13 11 9 7-1
kontener para - wczytywanie // *3* ------------------------------------ przed programem struct pair_si { int first; string second; bool operator < (const pair_si& p) const { return first == p.first? second < p.second : first < p.first; istream& operator >> (istream& ifs, pair_si& s) { static int licznik = 0; s.first = ++licznik; return ifs >> s.second; // *3* ------------------------------------ w programie typedef istream_iterator<pair_si> is; ifstream file("test.txt"); if (!file) return -1; list<pair_si> w; copy(is(file), is(), back_inserter(w));
para w liście uniwersalny sposób na wysłanie do strumienia // *4* ------------------------------------ przed programem template<typename T> struct output_pair { output_pair(ostream& o, string e = "") : strumien(o), koniec(e) { void operator () (const T& p) { strumien << p.first << '\t' << p.second << koniec; private: ostream& strumien; string koniec; template <typename T> void view(t con) { for_each(con.begin(), con.end(), output_pair<typename T::value_type>(cout, " ")); // value_type - typ przechowywanego obiektu // *4* ------------------------------------ w programie view(w);
obiekty funkcyjne vs wyrażenie lambda usuwanie // *5* ------------------------------------ przed programem class ffoe { public: ffoe(const string& e) : extra(e) { pair_si& operator () (pair_si& w) { string::size_type p; while ((p = w.second.find_first_of(extra))!= string::npos) w.second.erase(p, 1); return w; protected: string extra; // *5* ------------------------------------ w programie transform(w.begin(), w.end(), w.begin(), ffoe("y")); view( w ); vector<int> v5 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 transform( v5.begin(), v5.end(), v5.begin(), [](int i)->int { cout << "kwadrat z "<<i<<" = "<<i*i<<endl; return i*i; );
// *6* ------------------------------------ przed programem class ssort { public: bool operator () (const pair_si& l, const pair_si& r) { return l.second < r.second; // *6* ------------------------------------ w programie w.sort( ssort() ); w.sort( [] (const pair_si& p1, const pair_si& p2) { return p1.first > p2.first; ); view(w); obiekty funkcyjne vs wyrażenie lambda sortowanie
obiekty funkcyjne sortowanie: zadanie Proszę napisać: a) obiekt funkcyjny lub b) wyrażenie lambda za pomocą których posortowane będą obiekty klasy Kot (jak poniżej) według kryterium od najdłuższej nazwy (w sensie liczby liter w nazwie) do najkrótszej, umieszczone w wektorze. Jeśli długość nazwy jest ta sama, sortować wg ogólnych reguł bez uwzględniania wielkości liter. class Kot { string nazwa; public: Kot( const char* n ) : nazwa(n) { // w klasie dopisać co trzeba vector<kot> v { "Jaga", "Badyl", "Kicia", "Mruczek", "Alfred", "Bazyli" Wynik sortowania wypisać na ekran (można dopisać jakąś metodę dostępową w klasie lub przeciążyć operator<< dla typu Kot).
// *7* ------------------------------------ przed programem typedef map<string, int> stat_map; class stat { public: stat(stat_map& msi_) : msi(msi_) { void operator () (const pair_si& s) { msi[s.second]++; protected: stat_map& msi; // *7* ------------------------------------ w programie stat_map st; for_each(w.begin(), w.end(), stat(st)); view(st); obiekty funkcyjne przepisywanie do mapy
// *8* ------------------------------------ w programie ostream_iterator<int> os(cout, " "); list<int> l2 = {11, 2, 13, 1, -7, 9, -1 // l2.remove_if(bind1st(less<int>(), 1)); l2.remove_if( bind( less<int>(), _1, 1 ) ); // l2.remove_if(bind2nd(less<int>(), 1)); // l2.remove_if( [](int i){ return i<1; ); copy( l2.begin(), l2.end(), os ); // 11 2 13 1 9 obiekty funkcyjne
obiekty funkcyjne // *9* ------------------------------------ przed programem struct mniej_niz2 : public unary_function <int, bool> { mniej_niz2 ( int x_ ) : x ( x_ ) { bool operator () (int y) const { return y < x; private: int x; // *9* ------------------------------------ w programie l2.remove_if( mniej_niz2(5) ); copy(l2.begin(), l2.end(), os); // 13 11 9 l2.remove_if( not1( mniej_niz2(10) ) ); copy( l2.begin(), l2.end(), os ); // 9
obiekty funkcyjne // *10* ------------------------------------ przed programem class E { public: E(int e) : e_(e) { template<typename T> void foo() { cout << e_; struct pointer { void bar() const { cout << 10+e_; T* operator() (T& t) { return &t; private: int e_; // *10* ------------------------------------ w programie E t3[] = {9, 1, 8, 2, 7, 3, 6, 4, 5, 0 // for_each(t3, t3+10, mem_fun_ref(&e::foo)); // 9182736450 for_each(t3, t3+10, bind(&e::foo,_1)); // 9182736450 list<const E*> l3; transform(t3, t3+10, back_inserter(l3), pointer<e>()); //for_each(l3.begin(), l3.end(), mem_fun(&e::bar)); // 19111812171316141510 for_each(l3.begin(), l3.end(), bind(&e::bar,_1)); // 19111812171316141510