Note that there are some explanatory texts on larger screens.

plurals
  1. POunexpected std::bad_function_call in recursion
    primarykey
    data
    text
    <p>I have written the following code, which plays with functions of type <code>function&lt;int(int)&gt;</code>. The functions <code>compose</code>, <code>print</code>, <code>inc</code> and <code>guarded</code> are helpers which combine other functions or produce some external effect. Then I use them to build my programs:</p> <pre><code>/* start of the program */ function&lt;int(int)&gt; recursion(); function&lt;int(int)&gt; go = compose(guarded(10, recursion()), compose(inc, print("go"))); function&lt;int(int)&gt; recursion() { return compose(go, print("recursion")); } </code></pre> <p>However, when calling <code>recursion()(0)</code>, an exception <code>std::bad_function_call</code> was thrown when <code>go</code> was reached the second time but I don't see why. Is there any dangling reference or empty <code>std::function</code>? Moreover, eta-expanding <code>go</code> works:</p> <pre><code>function&lt;int(int)&gt; go = [](int n) -&gt; int { return compose(guarded(10, recursion()), compose(inc, print("go")))(n); }; </code></pre> <p>What's wrong with the original code? Why does the alternative one work?</p> <p>Full code:</p> <pre><code>#include &lt;string&gt; #include &lt;iostream&gt; #include &lt;functional&gt; using namespace std; /* helper functions, some combinators */ //composing two functions, f1 . f2 function&lt;int(int)&gt; compose(const function&lt;int(int)&gt;&amp; f1, const function&lt;int(int)&gt;&amp; f2) { return [f1,f2](int n) -&gt; int { return f1(f2(n)); }; } function&lt;int(int)&gt; print(const string&amp; msg) { return [msg](int n) -&gt; int { cout &lt;&lt; "print: " &lt;&lt; msg &lt;&lt; endl; return n; }; } function&lt;int(int)&gt; inc = [](int n) -&gt; int { cout &lt;&lt; "in inc lambda: " &lt;&lt; n &lt;&lt; endl; return n+1; }; //calls the given function `f` only when `n` is less then `m` function&lt;int(int)&gt; guarded(int m, function&lt;int(int)&gt; f) { auto g = [m,f](int n) -&gt; int { return n&lt;m? f(n) : m; }; return compose(g, print("guarded")); } /* start of the program */ function&lt;int(int)&gt; recursion(); function&lt;int(int)&gt; go = compose(guarded(10, recursion()), compose(inc, print("go"))); function&lt;int(int)&gt; recursion() { return compose(go, print("recursion")); } int main() { try { recursion()(0); } catch (bad_function_call e) { cout &lt;&lt; "bad_function_call: " &lt;&lt; e.what() &lt;&lt; endl; } return 0; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload