{"id":103745,"date":"2020-05-13T07:00:00","date_gmt":"2020-05-13T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=103745"},"modified":"2023-08-02T13:13:33","modified_gmt":"2023-08-02T20:13:33","slug":"20200513-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200513-00\/?p=103745","title":{"rendered":"Inside <CODE>std::function<\/CODE>, part 1: The basic idea"},"content":{"rendered":"<p>The C++ language standard library comes with a <code>std::function<\/code> template type which represents a &#8220;thing you can invoke&#8221;. It can hold any callable, such as<\/p>\n<ul>\n<li>Function pointer.<\/li>\n<li>Lambda.<\/li>\n<li>Other object with <code>operator()<\/code>.<\/li>\n<\/ul>\n<p>The way this is done is with the assistance of a polymorphic helper object that understands the specific callable it is wrapping.<\/p>\n<p>Here&#8217;s a sketch. For concreteness, let&#8217;s say we&#8217;re implementing <code>std::function&lt;bool(int, char*)&gt;<\/code>. For readability, I&#8217;ve de-uglified\u00b9 the identifiers.<\/p>\n<pre>struct callable_base\r\n{\r\n  callable_base() = default;\r\n  virtual ~callable_base() { }\r\n  virtual bool invoke(int, char*) = 0;\r\n  virtual unique_ptr&lt;callable_base&gt; clone() = 0;\r\n};\r\n\r\ntemplate&lt;typename T&gt;\r\nstruct callable : callable_base\r\n{\r\n  T m_t;\r\n\r\n  callable(T const&amp; t) : m_t(t) {}\r\n  callable(T&amp;&amp; t) : m_t(move(t)) {}\r\n\r\n  bool invoke(int a, char* b) override\r\n  {\r\n    return m_t(a, b);\r\n  }\r\n\r\n  unique_ptr&lt;callable_base&gt; clone() override\r\n  {\r\n    return make_unique&lt;callable&gt;(m_t);\r\n  }\r\n};\r\n\r\nstruct function\r\n{\r\n  std::unique_ptr&lt;callable_base&gt; m_callable;\r\n\r\n  template&lt;typename T&gt;\r\n  function(T&amp;&amp; t) :\r\n    m_callable(new callable&lt;decay_t&lt;T&gt;&gt;\r\n                (forward&lt;T&gt;(t)))\r\n  {\r\n  }\r\n\r\n  function(const function&amp; other) :\r\n    m_callable(other.m_callable ?\r\n               other.m_callable-&gt;clone() : nullptr)\r\n  {\r\n  }\r\n\r\n  function(function&amp;&amp; other) = default;\r\n\r\n  bool operator()(int a, char* b)\r\n  {\r\n    \/\/ TODO: bad_function_call exception\r\n    return m_callable-&gt;invoke(a, b);\r\n  }\r\n};\r\n<\/pre>\n<p>The idea is that each <code>function<\/code> has a <code>callable_base<\/code>, which is an interface that allows us to perform basic operations on callable objects: Create a copy, invoke it, and destroy it. Invoking the <code>function<\/code> forwards the invoke to the <code>callable_base<\/code>. Copying the <code>function<\/code> requires a special <code>clone<\/code> method on the <code>callable_base<\/code>, because <code>unique_ptr<\/code> is not copyable.<\/p>\n<p>Constructing the <code>function<\/code> is a matter of creating a custom <code>callable<\/code> for the specific functor. It&#8217;s conceptually simple, but the C++ language makes us write out a bunch of stuff to get it to work. We just want a callable that wraps the thing that was passed to the constructor.<\/p>\n<p>The <code>std::function<\/code> in the standard library is basically like this, but with additional optimizations to avoid an allocation in the case of a small <code>callable<\/code>. Said optimizations are in fact mandatory by the standard if the callable is a plain function pointer or a <code>reference_wrapper<\/code>.<\/p>\n<p>We&#8217;ll look at that optimization next time, because it gives us some insight into how we can do similar things with our own types.<\/p>\n<p>\u00b9 Uglification is the process of taking readable names and transforming them into names that are reserved for the implementation. Different libraries have different uglification conventions. For the Microsoft Visual C++ implementation of the standard library, the uglifications tend to be<\/p>\n<ul>\n<li><code>_My<\/code> prefix for member variables.<\/li>\n<li><code>_Ty<\/code> prefix for type names.<\/li>\n<li><code>_Fn<\/code> prefix for functors.<\/li>\n<li><code>_P<\/code> prefix for pointers.<\/li>\n<li><code>_<\/code> (and capital first letter) for most other things.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Holding all different kinds of things.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-103745","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Holding all different kinds of things.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103745","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=103745"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103745\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=103745"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=103745"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=103745"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}