User Tools

Site Tools


cpp:functors

This is an old revision of the document!


Function Objects ή Functors

Συχνά στην STL θέλουμε να εφαρμόσουμε μία συνάρτηση πάνω στο περιεχόμενο ενός container προκειμένου να μεταβάλλουμε το περιεχόμενο του ή να αποθηκεύσουμε το αλλαγμένο περιεχόμενο σε ένα διαφορετικό από το αρχικό container.

Η συνάρτηση for_each

Η συνάρτηση std::for_each επιτρέπει την μεταβολή του περιεχομένου οποιουδήποτε container από μία συνάρτηση. Παρακάτω δίνεται ένα παράδειγμα, όπου στα περιεχόμενα ενός vector<string> προστίθεται το prefix “light”:

prefix_str.cpp
#include <vector>
#include <list>
#include <algorithm>
#include <iostream>
#include <iomanip>
 
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
template<typename T>
void print(vector<T> v) {
  for(auto it = v.cbegin(); it!=v.cend(); it++) 
    cout << *it << ", ";
  cout << endl;
}
 
void prefixMe(string& str) {
  str = "light " + str;
}
 
int main() {
  vector<string> colors;
 
  colors.push_back("red");
  colors.push_back("green");
  colors.push_back("blue");
 
  print(colors);
  for_each(colors.begin(), colors.end(), prefixMe);
  print(colors);
}

Παρατηρήστε ότι ο κώδικας δουλεύει σωστά, με την υποσημείωση ότι κάθε φορά που θέλετε να αλλάξετε το prefix το οποίο προστίθεται στα περιεχόμενα του container πρέπει να γράφετε μία νέα συνάρτηση. Αντί για αυτό θα μπορούσαμε να χρησιμοποιήσουμε ένα αντικείμενο ως συνάρτηση το οποίο να έχει τα εξής χαρακτηριστικά:

  1. διαθέτει ένα πεδίο το οποίο περιέχει το prefix που θα προστεθεί.
  2. υπερφορτώνει τον τελεστή () (operator()) με ένα μόνο όρισμα τύπου std::string, ώστε να μπορούμε να το χρησιμοποιήσουμε ως συνάρτηση.

Ένα τέτοιο αντικείμενο ονομάζεται function object ή functor. Δείτε το παρακάτω παράδειγμα όπου ορίζουμε την κλάση PrefixString, η οποία δημιουργεί ένα function object.

prefix_str_function_object.cpp
#include <vector>
#include <algorithm>
#include <iostream>
 
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
template<typename T>
void print(vector<T> v) {
  for(auto it = v.cbegin(); it!=v.cend(); it++) 
    cout << *it << ", ";
  cout << endl;
}
 
class PrefixString {
  string prefix;
public:
  PrefixString(string p): prefix(p) {}
  void operator()(string& str) {
    str = prefix + str;
  }
};
 
int main() {
  vector<string> colors;
 
  colors.push_back("red");
  colors.push_back("green");
  colors.push_back("blue");
 
  print(colors);
  for_each(colors.begin(), colors.end(), PrefixString("light "));
  print(colors);
}
cpp/functors.1590957150.txt.gz · Last modified: 2020/05/31 19:32 (external edit)