{"id":1169,"date":"2013-07-22T01:00:00","date_gmt":"2013-07-21T23:00:00","guid":{"rendered":"https:\/\/www.fussylogic.co.uk\/blog\/?p=1169"},"modified":"2013-08-05T14:13:23","modified_gmt":"2013-08-05T13:13:23","slug":"delegation-2","status":"publish","type":"post","link":"https:\/\/www.fussylogic.co.uk\/blog\/?p=1169","title":{"rendered":"Delegation"},"content":{"rendered":"<p><a href=\"?p=1156\">Last time<\/a>, I spoke about lambdas, and left you with this comment about other features of lambdas.<\/p>\n<blockquote>\n<p>One that\u00e2\u20ac\u2122s particularly worth bearing in mind is the ability to pass <code>this<\/code> as a lambda parameter. That means you can get access to more than just the enclosing scope variables, you can get access to the enclosing object.<\/p>\n<\/blockquote>\n<p>It might not be immediately obvious why it\u00e2\u20ac\u2122s so useful to be able to put an object reference in a lambda. The fact is that it doesn\u00e2\u20ac\u2122t have to be <code>[this]<\/code> that you pass; any lambda with a reference to an object has effectively created a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Delegation_%28programming%29\">delegate<\/a>. This is particularly important if you create a lambda that is intended to be longer lived, that you will return or pass around rather than use instantly and discard.<\/p>\n<p>Before I begin on that subject, let\u00e2\u20ac\u2122s look a little bit at functors. I previously was a little cavalier and treated them as if they were indistinguishable from function pointers. Unfortunately that\u00e2\u20ac\u2122s only true in the no-parameter-constructor case. It\u00e2\u20ac\u2122s definitely not true that a pointer to a class with an <code>operator()()<\/code> implementation is the same as a pointer to a function \u00e2\u20ac\u201c a pointer to a function has a real address; an <code>operator()()<\/code> of an object cannot have its address taken. Lambda references are different again. C++11 fortunately introduces a class that let\u00e2\u20ac\u2122s us ignore the differences, <code>std::function<\/code>.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"ot\">#include &lt;functional&gt;<\/span>\n\n<span class=\"dt\">void<\/span> functionTakingFunction( std::function&lt;<span class=\"dt\">void<\/span> (<span class=\"dt\">int<\/span>)&gt; f ) {\n    f(<span class=\"dv\">10<\/span>);\n}<\/code><\/pre>\n<p>The parameter here can be a C-compatible pointer-to-function, a functor, or a lambda. We don\u00e2\u20ac\u2122t need to care. Back to the plot\u00e2\u20ac\u00a6<\/p>\n<p>A delegate lets you tell it about object A, and then pass the delegate as a callback to object B \u00e2\u20ac\u201c object B then never needs to know about object A \u00e2\u20ac\u201c in particular, that it is calling an instance rather than a static member.<\/p>\n<p>Here\u00e2\u20ac\u2122s an example of delgation that you may already have used without realising it was delegation. Imagine you are wrapping a C library in a C++ object. The library implements a callback facility to, say, let you know when it has finished some task.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">library_taskfinished( libraryHandle, myFunction, myOpaquePtr );<\/code><\/pre>\n<p>You\u00e2\u20ac\u2122ve wrapped the <code>libraryHandle<\/code> in an class and in the constructor you want to make sure that this callback gets routed to this instance. The problem is that instance methods are not normal functions, they require an instance pointer to be passed to them (the compiler generates that code for you). The solution is this:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">class TLibrary {\n  public:\n    TLibrary() {\n        libraryHandle = library_createhandle();\n        library_taskfinished( libraryHandle, taskFinishedStatic, this );\n    }\n  private:\n    <span class=\"dt\">static<\/span> <span class=\"dt\">void<\/span> taskFinishedStatic( <span class=\"dt\">void<\/span> *opaque ) {\n        TLibrary *objectPointer = reinterpret_cast&lt;TLibrary*&gt;(opaque);\n        objectPointer-&gt;taskFinished();\n    }\n    virtual <span class=\"dt\">void<\/span> taskFinished() = <span class=\"dv\">0<\/span>;\n\n  private:\n    <span class=\"kw\">struct<\/span> sLibraryHandle *libraryHandle;\n};<\/code><\/pre>\n<p>The static acts as half of a delegate. A static is a normal function pointer, whose address can be taken, so it can be used as a C callback. The library is willing to store an opaque pointer (this is almost universal for callback-using libraries) that it promises to hand back to us in the callback. The pointer is opaque to the library, but it is not opaque to <code>taskFinishedStatic()<\/code>, which casts it back to a <code>TLibrary*<\/code> instance pointer and calls the member function <code>taskFinished()<\/code>. We\u00e2\u20ac\u2122re implementing a wrapper, so we can\u00e2\u20ac\u2122t say what <code>taskFinished()<\/code> should do either \u00e2\u20ac\u201c but it is a virtual member, so the user of the wrapper can implement as appropriate for them.<\/p>\n<p>Now, imagine that the library didn\u00e2\u20ac\u2122t take an opaque pointer. We would have no way of finding out the original object. Unless the library was a C++ library and accepted a <code>std::function<\/code> parameter; and then we could pass a real-life delegate.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">class TLibrary {\n  public:\n    TLibrary() {\n        libraryHandle = library_createhandle();\n        library_taskfinished( libraryHandle,\n            [this](){this-&gt;taskFinished();} );\n    }\n  private:\n    virtual <span class=\"dt\">void<\/span> taskFinished() = <span class=\"dv\">0<\/span>;\n\n  private:\n    <span class=\"kw\">struct<\/span> sLibraryHandle *libraryHandle;\n};<\/code><\/pre>\n<p>The delegate is a lambda, constructed inline with a note of its creating class. That note allows it, when it is later called by the library, to take the place of <code>taskFinishedStatic()<\/code>. It needs no cast because it knows the type of its parameter, <code>this<\/code>.<\/p>\n<p>While this is a good example of delegation, it\u00e2\u20ac\u2122s a bad practical example. It relied on the C library supporting a C++ class as a parameter \u00e2\u20ac\u201c of course it won\u00e2\u20ac\u2122t. It\u00e2\u20ac\u2122s impossible that the C library function <code>library_taskfinished()<\/code> takes a <code>std::function<\/code> as its parameter.<\/p>\n<p>However, let\u00e2\u20ac\u2122s use the semi-delegate trick we used for <code>TLibrary::taskFinishedStatic()<\/code> to bridge the gap, but this time it will bridge the gap for <code>std::function<\/code> not just one specific case like <code>TLibrary<\/code>.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"ot\">#include &lt;functional&gt;<\/span>\n<span class=\"ot\">#include &lt;iostream&gt;<\/span>\nusing namespace std;\n\n<span class=\"co\">\/\/ Want a C-style function-pointer-accepting function<\/span>\n<span class=\"kw\">extern<\/span> <span class=\"st\">&quot;C&quot;<\/span> <span class=\"dt\">int<\/span> instant_callback( <span class=\"dt\">int<\/span> (*cb)(<span class=\"dt\">void<\/span> *), <span class=\"dt\">void<\/span> *opaque) {\n    <span class=\"co\">\/\/ A real library would provide a function that let the caller set a<\/span>\n    <span class=\"co\">\/\/ function and pointer to be used as a callback in response to some<\/span>\n    <span class=\"co\">\/\/ event.  We&#39;re just testing, so rather than noting the callback<\/span>\n    <span class=\"co\">\/\/ and opaque pointer for later, we just call it instantly<\/span>\n    <span class=\"kw\">return<\/span> cb(opaque);\n}\n\n<span class=\"co\">\/\/<\/span>\n<span class=\"co\">\/\/ Class: functor_as_c_function&lt;&gt;<\/span>\n<span class=\"co\">\/\/ Description:<\/span>\n<span class=\"co\">\/\/  Turns a C-incompatible functor into a C-compatible callback.  The<\/span>\n<span class=\"co\">\/\/  trick is to have inserted a static (which is just a function) to<\/span>\n<span class=\"co\">\/\/  capture an opaque pointer back from the caller of the callback, and<\/span>\n<span class=\"co\">\/\/  then cast it to the C++ function type that we know it is, and call<\/span>\n<span class=\"co\">\/\/  that.<\/span>\n<span class=\"co\">\/\/<\/span>\ntemplate&lt;typename F&gt;\nclass functor_as_c_function {\n    using R = typename F::result_type;\n  public:\n    <span class=\"dt\">static<\/span> R c_function( <span class=\"dt\">void<\/span> *opaque ) {\n        F &amp;transparent = *(reinterpret_cast&lt;F*&gt;(opaque));\n        <span class=\"kw\">return<\/span> transparent();\n    }\n};\n\n<span class=\"dt\">int<\/span> main()\n{\n    <span class=\"co\">\/\/ A functor, and a typedef for the callback-creating helper<\/span>\n    function&lt;<span class=\"dt\">int<\/span>()&gt; mFunctor;\n    <span class=\"kw\">typedef<\/span> functor_as_c_function&lt;decltype(mFunctor)&gt; cf;\n    \n    <span class=\"co\">\/\/ Lambdas are the easiest functors to create<\/span>\n    <span class=\"dt\">int<\/span> x = <span class=\"dv\">10<\/span>;\n    mFunctor = [&amp;x](){ <span class=\"kw\">return<\/span> x; };\n\n    <span class=\"co\">\/\/ Should be 10<\/span>\n    clog &lt;&lt; instant_callback(cf::c_function, &amp;mFunctor) &lt;&lt; endl;\n\n    x = <span class=\"dv\">11<\/span>;\n\n    <span class=\"co\">\/\/ Should display 11, as the functor took x by reference<\/span>\n    clog &lt;&lt; instant_callback(cf::c_function, &amp;mFunctor) &lt;&lt; endl;\n\n    <span class=\"kw\">return<\/span> <span class=\"dv\">0<\/span>;\n}<\/code><\/pre>\n<p>We can go a step further. We can solve the problem that is addressed in <a href=\"http:\/\/tia.mat.br\/blog\/html\/2013\/07\/20\/partial_functions_in_c.html\">this article<\/a> about partial functions in C. The problem addressed there is when a callback doesn\u00e2\u20ac\u2122t even allow an opaque pointer to be passed. The library functions <code>atexit()<\/code> and <code>signal()<\/code> both have this drawback. The article solves the problem with a clever hack \u00e2\u20ac\u201c by creating a function pointer that encodes parameter information in it. We can do better than that though, without needing to touch assembly.<\/p>\n<p>We cheat by making the function call itself hold the opaque pointer. Effectively delegating again. Using templates we can get the compiler to manufacturer us such a function on the fly.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"co\">\/\/ This is a simulation of a really unpleasant callback; the library<\/span>\n<span class=\"co\">\/\/ writer hasn&#39;t given us an opaque pointer.<\/span>\n<span class=\"kw\">extern<\/span> <span class=\"st\">&quot;C&quot;<\/span> <span class=\"dt\">int<\/span> bare_instant_callback( <span class=\"dt\">int<\/span> (*cb)(<span class=\"dt\">void<\/span>*) );\n\ntemplate&lt;<span class=\"dt\">int<\/span>(*opaqueFunction)(<span class=\"dt\">void<\/span>*), <span class=\"dt\">void<\/span> *GlobalOpaque&gt;\nclass bare_wrapping_callback {\n  public:\n    <span class=\"dt\">static<\/span> <span class=\"dt\">int<\/span> callback_with_opaque() {\n        <span class=\"kw\">return<\/span> opaqueFunction(GlobalOpaque);\n    }\n};<\/code><\/pre>\n<p>In this way we\u00e2\u20ac\u2122ve effectively stored the opaque pointer as a constant inside the function. The drawback here is that the <em>GlobalOpaque<\/em> has to be globally accessible.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last time, I spoke about lambdas, and left you with this comment about other features of lambdas. One that\u00e2\u20ac\u2122s particularly worth bearing in mind is the ability to pass this as a lambda parameter. That means you can get access to more than just the enclosing scope variables, you can get access to the enclosing\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.fussylogic.co.uk\/blog\/?p=1169\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[66,82,96,6],"_links":{"self":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1169"}],"collection":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1169"}],"version-history":[{"count":4,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1169\/revisions"}],"predecessor-version":[{"id":1177,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1169\/revisions\/1177"}],"wp:attachment":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1169"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1169"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1169"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}