What are C++ functors and their uses?

后端 未结 14 1498
花落未央
花落未央 2020-11-21 04:27

I keep hearing a lot about functors in C++. Can someone give me an overview as to what they are and in what cases they would be useful?

14条回答
  •  时光说笑
    2020-11-21 04:40

    A big advantage of implementing functions as functors is that they can maintain and reuse state between calls. For example, many dynamic programming algorithms, like the Wagner-Fischer algorithm for calculating the Levenshtein distance between strings, work by filling in a large table of results. It's very inefficient to allocate this table every time the function is called, so implementing the function as a functor and making the table a member variable can greatly improve performance.

    Below is an example of implementing the Wagner-Fischer algorithm as a functor. Notice how the table is allocated in the constructor, and then reused in operator(), with resizing as necessary.

    #include 
    #include 
    #include 
    
    template 
    T min3(const T& a, const T& b, const T& c)
    {
       return std::min(std::min(a, b), c);
    }
    
    class levenshtein_distance 
    {
        mutable std::vector > matrix_;
    
    public:
        explicit levenshtein_distance(size_t initial_size = 8)
            : matrix_(initial_size, std::vector(initial_size))
        {
        }
    
        unsigned int operator()(const std::string& s, const std::string& t) const
        {
            const size_t m = s.size();
            const size_t n = t.size();
            // The distance between a string and the empty string is the string's length
            if (m == 0) {
                return n;
            }
            if (n == 0) {
                return m;
            }
            // Size the matrix as necessary
            if (matrix_.size() < m + 1) {
                matrix_.resize(m + 1, matrix_[0]);
            }
            if (matrix_[0].size() < n + 1) {
                for (auto& mat : matrix_) {
                    mat.resize(n + 1);
                }
            }
            // The top row and left column are prefixes that can be reached by
            // insertions and deletions alone
            unsigned int i, j;
            for (i = 1;  i <= m; ++i) {
                matrix_[i][0] = i;
            }
            for (j = 1; j <= n; ++j) {
                matrix_[0][j] = j;
            }
            // Fill in the rest of the matrix
            for (j = 1; j <= n; ++j) {
                for (i = 1; i <= m; ++i) {
                    unsigned int substitution_cost = s[i - 1] == t[j - 1] ? 0 : 1;
                    matrix_[i][j] =
                        min3(matrix_[i - 1][j] + 1,                 // Deletion
                        matrix_[i][j - 1] + 1,                      // Insertion
                        matrix_[i - 1][j - 1] + substitution_cost); // Substitution
                }
            }
            return matrix_[m][n];
        }
    };
    

提交回复
热议问题