Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Some time has passed, C++14 is being finalized, and compilers are adding support for new features, like generic lambdas.</p> <p>Generic lambdas, together with the machinery shown below, allow achieving the desired (dynamic) polymorphism with unrelated classes:</p> <pre><code>#include &lt;boost/variant.hpp&gt; template&lt;typename R, typename F&gt; class delegating_visitor : public boost::static_visitor&lt;R&gt; { public: delegating_visitor(F&amp;&amp; f) : _f(std::forward&lt;F&gt;(f)) { } template&lt;typename T&gt; R operator () (T x) { return _f(x); } private: F _f; }; template&lt;typename R, typename F&gt; auto make_visitor(F&amp;&amp; f) { using visitor_type = delegating_visitor&lt;R, std::remove_reference_t&lt;F&gt;&gt;; return visitor_type(std::forward&lt;F&gt;(f)); } template&lt;typename R, typename V, typename F&gt; auto vcall(V&amp;&amp; vt, F&amp;&amp; f) { auto v = make_visitor&lt;R&gt;(std::forward&lt;F&gt;(f)); return vt.apply_visitor(v); } #define call_on_variant(val, fxn_expr) \ vcall&lt;int&gt;(val, [] (auto x) { return x-&gt; fxn_expr; }); </code></pre> <p>Let's put this into practice. Supposing to have the following two unrelated classes:</p> <pre><code>#include &lt;iostream&gt; #include &lt;string&gt; struct A { int foo(int i, double d, std::string s) const { std::cout &lt;&lt; "A::foo(" &lt;&lt; i &lt;&lt; ", " &lt;&lt; d &lt;&lt; ", " &lt;&lt; s &lt;&lt; ")"; return 1; } }; struct B { int foo(int i, double d, std::string s) const { std::cout &lt;&lt; "B::foo(" &lt;&lt; i &lt;&lt; ", " &lt;&lt; d &lt;&lt; ", " &lt;&lt; s &lt;&lt; ")"; return 2; } }; </code></pre> <p>It is possible to invoke <code>foo()</code> polymorphically this way:</p> <pre><code>int main() { A a; B b; boost::variant&lt;A*, B*&gt; v = &amp;a; auto res1 = call_on_variant(v, foo(42, 3.14, "Hello")); std::cout &lt;&lt; std::endl&lt;&lt; res1 &lt;&lt; std::endl; v = &amp;b; auto res2 = call_on_variant(v, foo(1337, 6.28, "World")); std::cout &lt;&lt; std::endl&lt;&lt; res2 &lt;&lt; std::endl; } </code></pre> <p>And the output is, as expected:</p> <pre><code>A::foo(42, 3.14, Hello) 1 B::foo(1337, 6.28, World) 2 </code></pre> <p>The program has been tested on VC12 with November 2013's CTP. Unfortunately, I do not know of any online compiler that supports generic lambdas, so I cannot post a live example.</p>
 

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