{"id":330,"date":"2019-02-27T22:03:15","date_gmt":"2019-02-28T06:03:15","guid":{"rendered":"http:\/\/35.243.195.209\/?p=330"},"modified":"2019-03-19T22:03:34","modified_gmt":"2019-03-20T05:03:34","slug":"brief-introduction-to-functors","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2019\/02\/27\/brief-introduction-to-functors\/","title":{"rendered":"Brief Introduction to Functors"},"content":{"rendered":"<h2>Summary<\/h2>\n<p>In this post, I will introduce function objects, also known as functors. <\/p>\n<h2>Conclusion<\/h2>\n<p>I provid the following snippets as a quick reference. See <a href=\"https:\/\/leetcode.com\/problems\/meeting-rooms-ii\/\">meeting-rooms-II<\/a> for the problem details.<\/p>\n<pre><code class=\"language-c\">\/**\n * Definition for an interval.\n * struct Interval {\n *     int start;\n *     int end;\n *     Interval() : start(0), end(0) {}\n *     Interval(int s, int e) : start(s), end(e) {}\n * };\n *\/\nclass Solution {\npublic:\n    class CompareByStart {\n    public:\n        bool operator()(Interval const &amp; a, Interval const &amp; b) const {\n            return a.start &lt; b.start;\n        }\n    };\n    class CompareByEnd {\n    public:\n        bool operator()(Interval const &amp; a, Interval const &amp; b) const {\n            return a.end &lt; b.end;\n        }\n    };\n    int minMeetingRooms(vector&lt;Interval&gt;&amp; intervals) {\n        multiset&lt;Interval, CompareByEnd&gt; s; \n        CompareByStart cbs;\n        sort(intervals.begin(), intervals.end(), cbs);\n        for (auto const &amp; interval : intervals) {\n            if (s.size() == 0) {\n                s.insert(interval);\n            } else {\n                if ((*s.begin()).end &lt;= interval.start) {\n                    s.erase(s.begin());\n                    s.insert(interval);\n                } else {\n                    s.insert(interval);\n                }\n            }\n        }\n        return s.size();\n    }\n};<\/code><\/pre>\n<h2>Details<\/h2>\n<p>A functor is an object that acts like a function by overloading the function call operator (unary, binary, &#8230;). It is kind of functional programming in object oriented programming. <\/p>\n<p>Compared to pointers to functions, the calls of functors can be inlined in more cases, which is a great advantage. If you passed a function pointer to transform, unless that call got inlined and the compiler knows that you always pass the same function to it, it can&#8217;t inline the call through the pointer.<\/p>\n<p>Functors are commonly used in STL algorithms and containers. I present two examples. <\/p>\n<h3>std::transform<\/h3>\n<p>Functors can hold state before and between function calls, like closure in functional languages. For example, you could define a MultiplyBy functor that multiplies its argument by a specified amount:<\/p>\n<pre><code class=\"language-c\">class MultiplyBy {\nprivate:\n    int factor;\n\npublic:\n    MultiplyBy(int x) : factor(x) {\n    }\n\n    int operator () (int other) const {\n        return factor * other;\n    }\n};\nint main() {\n        int array[5] = {1, 2, 3, 4, 5};\n        std::transform(array, array + 5, array, MultiplyBy(3));\n        \/\/ Now, array is {3, 6, 9, 12, 15}\n        return 0;\n}<\/code><\/pre>\n<h3>std::multiset<\/h3>\n<p>Functors can be passed to many STL containers. It is more clear than using lambda expressions or function pointers. <\/p>\n<pre><code class=\"language-c\">bool fncomp (int lhs, int rhs) {return lhs&amp;lt;rhs;}\n\nstruct classcomp {\n    bool operator() (const int&amp;amp; lhs, const int&amp;amp; rhs) const\n    {return lhs&amp;lt;rhs;}\n};\n\nint main ()\n{\n    std::multiset&amp;lt;int&amp;gt; first;                          \/\/ empty multiset of ints\n\n    std::multiset&amp;lt;int,classcomp&amp;gt; multiset1;                \/\/ class as Compare\n\n    bool(*fn_pt)(int,int) = fncomp;\n    std::multiset&amp;lt;int,bool(*)(int,int)&amp;gt; multiset2 (fn_pt); \/\/ function pointer as Compare\n\n    auto comp = [](int lhs, int rhs) {return lhs&amp;lt;rhs;}; \/\/ lambda expressions\n    std::multiset&amp;lt;int, decltype(comp)&amp;gt; multiset3 (comp); \/\/ function pointer as Compare\n\n    return 0;\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Summary In this post, I will introduce function objects, also known as functors. Conclusion I provid the following snippets as a quick reference. See meeting-rooms-II for the problem details. \/** * Definition for an interval. * struct Interval { * int start; * int end; * Interval() : start(0), end(0) {} * Interval(int s, int&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5],"tags":[],"class_list":["post-330","post","type-post","status-publish","format-standard","hentry","category-c","category-proglang"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/330","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=330"}],"version-history":[{"count":5,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/330\/revisions"}],"predecessor-version":[{"id":394,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/330\/revisions\/394"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=330"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=330"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=330"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}