{"id":232979,"date":"2014-08-12T20:10:02","date_gmt":"2014-08-12T16:10:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=232979"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=232979","title":{"rendered":"<span class=\"post_title\">\u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f<\/span>"},"content":{"rendered":"<div class=\"content html_format\">     \t\u041d\u0430\u043c\u0435\u0434\u043d\u0438 \u043d\u0430 RSDN \u0431\u044b\u043b \u0437\u0430\u0434\u0430\u043d \u0442\u0430\u043a\u043e\u0439 \u0432\u043e\u043f\u0440\u043e\u0441:<br \/>  \u041f\u0443\u0441\u0442\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0430\u044f \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0439 \u0442\u0438\u043f  <\/p>\n<pre><code class=\"cpp\">class Base { virtual int foo() const = 0; }; class A : public Base { int foo() const { return 1; } }; class B : public Base { int foo() const { return 2; } }; class C : public Base { int foo() const { return 3; } }; class D : public Base { int foo() const { return 4; } };  Base* getconfig(char cfg) \/\/ \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043a\u0430 \u043e\u0442\u0432\u043b\u0435\u043a\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0443\u0431\u043e\u0440\u043a\u0443 \u043c\u0443\u0441\u043e\u0440\u0430 {   switch(cfg)   {   case 'a': return new A();   case 'b': return new B();   case 'c': return new C();   case 'd': return new D();   default: throw std::invalid_argument(&quot;bad type&quot;);   } } <\/code><\/pre>\n<p>  \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0430\u044f \u0435\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b  <\/p>\n<pre><code class=\"cpp\">int entry(Base* x, Base* y) { return x-&gt;foo()*10 + y-&gt;foo(); } <\/code><\/pre>\n<p>  \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a  <\/p>\n<pre><code class=\"cpp\">void run(char cx, char cy) { std::cout &lt;&lt; cx &lt;&lt; cy &lt;&lt; &quot; : &quot; &lt;&lt; entry(getconfig(cx), getconfig(cy)) &lt;&lt; std::endl; } <\/code><\/pre>\n<p>  \u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u043f\u0440\u043e\u0442\u0430\u0449\u0438\u0442\u044c \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u0438\u0437\u043c \u043d\u0430 \u0441\u0442\u0430\u0434\u0438\u044e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438?<br \/>  <a name=\"habracut\"><\/a><br \/>  \u041c\u043e\u0436\u043d\u043e! \u041d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0432\u044b\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043a\u043e\u0434 \u043c\u0435\u0445\u043e\u043c \u0432\u043d\u0443\u0442\u0440\u044c, \u0442\u043e \u0435\u0441\u0442\u044c, \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u0432 <b>continuation passing style<\/b> (CPS) \u2014 \u0438\u043b\u0438, \u043f\u043e-\u0440\u0443\u0441\u0441\u043a\u0438, \u2014 \u043d\u0430 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f\u0445.<\/p>\n<h5>\u0421\u043f\u0435\u0440\u0432\u0430 \u043d\u0430\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435, \u0432 \u043e\u0431\u0449\u0438\u0445 \u0447\u0435\u0440\u0442\u0430\u0445.<\/h5>\n<p>  \u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 z = f(g(x)), \u043c\u044b \u0435\u0433\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0442\u0430\u043a:  <\/p>\n<ol>\n<li>y = g(x)<\/li>\n<li>z = f(y)<\/li>\n<\/ol>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u044b\u0441\u0448\u0435\u0433\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0430 (\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0443\u044e \u043d\u0430 \u0432\u0445\u043e\u0434 \u0434\u0440\u0443\u0433\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e) G(x,k) = k(g(x)). \u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u00ab\u0432\u044b\u0447\u0438\u0441\u043b\u0438 g(x) \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044e k\u00bb (k \u2014 kontinuation, \u0447\u0430\u0441\u0442\u043e \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u00abk\u00bb, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c \u043e\u0442 \u00abc\u00bb \u2014 constant).<br \/>  \u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u043e\u0441\u044c: z = G(x,f)?<\/p>\n<p>  \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u043e\u0441\u044c! \u0412 C++ \u0432\u044b\u0432\u043e\u0434 \u0442\u0438\u043f\u043e\u0432 \u043e\u0434\u043d\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439: \u043f\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c \u043f\u043e\u0434\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0431\u0443\u0434\u044c \u0442\u043e \u0448\u0430\u0431\u043b\u043e\u043d \u0438\u043b\u0438 \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u043e \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043e\u043a. \u0415\u0441\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f g \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0439 \u0442\u0438\u043f, \u043e\u043d\u0430 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u0432 f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0431\u0435\u0437 \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043e \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e.<\/p>\n<h5>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/h5>\n<p>  f(g(h(x))) &lt;=&gt; H(x, \u03bb y.G(y, \u03bb z.f(z)))),<br \/>  \u0433\u0434\u0435 \u03bb t.expr(t) \u2014 \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 (\u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0435), \u0434\u0430 \u043f\u0440\u043e\u0441\u0442\u044f\u0442 \u043c\u043d\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438 \u043d\u0435-C++-\u043d\u044b\u0439, \u0430 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0442\u0438\u043b\u044c \u0437\u0430\u043f\u0438\u0441\u0438;<br \/>  H(x,k) = k(h(x))<br \/>  G(x,h) = k(g(x))<\/p>\n<p>  f(g(x),h(y)) &lt;=&gt; G(x, \u03bbu.H(y, \u03bbv.f(u,v)))<\/p>\n<p>  \u042d\u0442\u043e \u0432\u0435\u0434\u044c \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0430\u0434\u043e! \u0417\u0430 \u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0439 \u0434\u0435\u0442\u0430\u043b\u044c\u044e: <b>\u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0435 \u043b\u044f\u043c\u0431\u0434\u044b<\/b>.<br \/>  \u0421 \u043d\u0438\u043c\u0438 \u043d\u0430\u0448\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a:  <\/p>\n<pre><code class=\"cpp\"> template&lt;class K&gt; void getconfig(char cfg, K& kont) {   switch(cfg)   {   case 'a': kont(A()); break; \/\/ \u043a\u0441\u0442\u0430\u0442\u0438, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u044f\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0430 \u043a\u0443\u0447\u0435   case 'b': kont(B()); break;   case 'c': kont(C()); break;   case 'd': kont(D()); break;   default: std::cerr &lt;&lt; &quot;bad type&quot; &lt;&lt; std::endl; break; \/\/ \u0432\u043c\u0435\u0441\u0442\u043e \u0431\u0440\u043e\u0441\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f - \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435   } }  template&lt;class X, class Y, class K&gt; void entry(X&amp;&amp; x, Y&& y, K&& kont) {   kont(x.foo()*10 + y.foo()); }  template&lt;class N&gt; \/\/ \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u043b\u044e\u0431\u044b\u043c\u0438 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438, - \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u0438 \u043d\u0435\u0442? void finish(char cx, char cy, N sum) {   std::cout &lt;&lt; cx &lt;&lt; cy &lt;&lt; &quot; : &quot; &lt;&lt; sum &lt;&lt; std::endl; } \/\/ \u0438 \u0434\u0430\u0436\u0435 \u0442\u0430\u043a void finish(char cx, char cy, int           sum) { std::cout &lt;&lt; cx &lt;&lt; cy &lt;&lt; &quot; : &quot; &lt;&lt; &quot;int    &quot; &lt;&lt; sum &lt;&lt; std::endl; } void finish(char cx, char cy, unsigned      sum) { std::cout &lt;&lt; cx &lt;&lt; cy &lt;&lt; &quot; : &quot; &lt;&lt; &quot;uint   &quot; &lt;&lt; sum &lt;&lt; std::endl; } void finish(char cx, char cy, long          sum) { std::cout &lt;&lt; cx &lt;&lt; cy &lt;&lt; &quot; : &quot; &lt;&lt; &quot;long   &quot; &lt;&lt; sum &lt;&lt; std::endl; } void finish(char cx, char cy, unsigned long sum) { std::cout &lt;&lt; cx &lt;&lt; cy &lt;&lt; &quot; : &quot; &lt;&lt; &quot;ulong   &quot; &lt;&lt; sum &lt;&lt; std::endl; } void finish(char cx, char cy, double        sum) { std::cout &lt;&lt; cx &lt;&lt; cy &lt;&lt; &quot; : &quot; &lt;&lt; &quot;double &quot; &lt;&lt; sum &lt;&lt; std::endl; }  void run(char cx, char cy) {   getconfig(cx, [=](auto x) {     getconfig(cy, [=](auto y) {       entry(x, y, [=](auto sum) {         finish(cx,cy,sum);       })     })   }); } <\/code><\/pre>\n<p>  \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u0445\u043e\u0442\u044f \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u043e\u2026<br \/>  \u041e\u0434\u043d\u0430 \u0431\u0435\u0434\u0430: \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0435 \u043b\u044f\u043c\u0431\u0434\u044b \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 C++14.<\/p>\n<p>  \u0410 \u0431\u0435\u0437 \u043d\u0438\u0445 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043a\u0430\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u2014 \u043c\u0443\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0434\u0435\u043b\u043e. \u041d\u043e \u043d\u0435 \u0431\u0435\u0437\u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0435!<\/p>\n<p>  \u041f\u0440\u0438\u0431\u0435\u0433\u043d\u0435\u043c \u043a \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u0442\u0440\u044e\u043a\u0430\u043c.<\/p>\n<h5>\u041f\u0435\u0440\u0432\u044b\u0439 \u0442\u0440\u044e\u043a<\/h5>\n<p>  \u0422\u0438\u043f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c (\u043d\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u043c), \u043d\u043e \u0441\u0430\u043c\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u2014 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u043e\u0439. \u041a\u0430\u043a \u0442\u0430\u043a\u043e\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e? \u0410 \u0432\u043e\u0442 \u043a\u0430\u043a:  <\/p>\n<pre><code class=\"cpp\">struct getconfig_t {   template&lt;class K&gt;   void operator() (char cfg, K&& kont) const   {     switch(cfg)     {     case 'a': kont(A()); break;     case 'b': kont(B()); break;     case 'c': kont(C()); break;     case 'd': kont(D()); break;     default: std::cerr &lt;&lt; &quot;bad type&quot; &lt;&lt; std::endl; break;     }   } } const getconfig; \/\/ \u0437\u0430\u043e\u0434\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430  struct entry_t {   template&lt;class X, class Y, class K&gt;   void operator()(X&& x, Y&& y, K&& kont) const { kont(x.foo()*10 + y.foo()); } } const entry;  struct finish_t {   \/\/ \u0442\u0430\u043a \u043c\u044b \u043f\u0440\u0438\u0434\u0430\u043b\u0438 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443, \u043d\u043e \u0438 \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u0443 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043e\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438   \/\/ (\u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0436\u0438\u0437\u043d\u0438 \u044d\u0442\u043e \u0431\u044b\u043b\u0430 \u0431\u044b \u0440\u043e\u0441\u0441\u044b\u043f\u044c \u0442\u0438\u043f\u043e\u0432 void(int), void(unsigned) \u0438 \u0442.\u0434.   void operator()(int           sum) { std::cout &lt;&lt; &quot;int    &quot; &lt;&lt; sum &lt;&lt; std::endl; }   void operator()(unsigned      sum) { std::cout &lt;&lt; &quot;uint   &quot; &lt;&lt; sum &lt;&lt; std::endl; }   void operator()(long          sum) { std::cout &lt;&lt; &quot;long   &quot; &lt;&lt; sum &lt;&lt; std::endl; }   void operator()(unsigned long sum) { std::cout &lt;&lt; &quot;ulong  &quot; &lt;&lt; sum &lt;&lt; std::endl; }   void operator()(double        sum) { std::cout &lt;&lt; &quot;double &quot; &lt;&lt; sum &lt;&lt; std::endl; } } const finish; <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <code>entry(A(), B(), finish);<\/code>, \u043e\u0434\u043d\u0430\u043a\u043e, \u0434\u043b\u044f \u0432\u0441\u0435\u0439 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u0438\u0442\u044c \u043d\u0435\u0447\u0442\u043e \u0441\u0442\u0440\u0430\u0448\u043d\u043e\u0435: \u043e\u0431\u044a\u0435\u043a\u0442\u044b-\u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f  <\/p>\n<pre><code class=\"cpp\">struct F {   char cx, cy; \/\/ \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430   F(char cx, char cy) : cx(cx), cy(cy) {}   template&lt;class N&gt; void operator()(N sum) const { finish(cx,cy,sum); } };  template&lt;class X&gt; struct E {   char cx, cy;   X&& x;   E(char cx, char cy, X&& x) : cx(cx), cy(cy), x(x) {}   template&lt;class Y&gt; void operator()(Y&& y) const { entry(x,y, F(cx,cy)); } };  struct G {   char cx, char cy;   G(char cx, char cy) : cx(cx), cy(cy) {}   template&lt;class X&gt; void operator()(X&& x) const { getconfig(cy, E&lt;X&gt;(cx,cy,x)); } };  void run(char cx, char cy) { getconfig(cx, G(cx,cy)); } <\/code><\/pre>\n<p>  \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0432 <i>\u0441\u0442\u0430\u0440\u043e\u043c<\/i> \u0434\u043e\u0431\u0440\u043e\u043c C++ \u0435\u0441\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u0441\u0442\u0440\u043e\u044f\u0449\u0430\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0435 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f, \u2014 \u043f\u043e \u0441\u0443\u0442\u0438, \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0434\u0435\u0440\u0435\u0432\u044c\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u042d\u0442\u043e std::bind, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0430\u044f \u0438\u0437 boost::bind.<br \/>  \u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 <code>bind(foo, x, _1)<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0430\u0436\u0435 \u043d\u0435 \u043e\u0434\u043d\u043e\u043c\u0435\u0441\u0442\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0430 \u043d\u0435-\u043c\u0435\u043d\u0435\u0435-\u0447\u0435\u043c \u043e\u0434\u043d\u043e\u043c\u0435\u0441\u0442\u043d\u0443\u044e, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0443\u044e \u043b\u044e\u0431\u044b\u0435 \u0442\u0438\u043f\u044b, \u043b\u0438\u0448\u044c \u0431\u044b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0431\u044b\u043b \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c \u0441 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 foo: <code>bind(foo, x, _1)(100, 200, &quot;bar&quot;)<\/code>.<br \/>  \u0422\u0430\u043a\u0430\u044f \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0434\u043b\u044f \u043d\u0430\u0441 \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u0430, \u043d\u043e \u043b\u0443\u0447\u0448\u0435 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435, \u043d\u0435 \u043f\u0440\u0430\u0432\u0434\u0430 \u043b\u0438?<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c\u2026  <\/p>\n<pre><code class=\"cpp\">#include &lt;functional&gt; using namespace std; \/\/ bind using namespace std::placeholders; \/\/ _1, _2  void run(char cx, char cy) {   getconfig(cx,     bind(getconfig, cy,       bind(entry, _1, _2,         bind(finish, cx, cy, _1)       )     )   ); } <\/code><\/pre>\n<p>  \u0418, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u044d\u0442\u043e \u0434\u043e\u0431\u0440\u043e \u043d\u0435 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f! \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e bind \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0434\u0435\u0440\u0435\u0432\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 bind \u2014 \u043d\u0435 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0430\u0441\u0442\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u2014 \u043f\u043e \u0441\u0443\u0442\u0438, \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043a\u043e\u0431\u043a\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430().<br \/>  \u0411\u0435\u0437 CPS \u0438 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0430 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c  <\/p>\n<pre><code class=\"cpp\">bind(finish, _1, _2, bind(entry, bind(getconfig, _1), bind(getconfig, _2))) (cx, cy); <\/code><\/pre>\n<p>  \u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f \u2014 cx \u0438 cy \u2014 \u0431\u044b\u043b\u0438 \u0431\u044b \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432\u043e \u0432\u0441\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0441\u0442\u0430 \u044d\u0442\u043e\u0439 \u043c\u0435\u0433\u0430-\u0444\u043e\u0440\u043c\u0443\u043b\u044b.<\/p>\n<h5>\u0412\u0442\u043e\u0440\u043e\u0439 \u0442\u0440\u044e\u043a<\/h5>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 bind&#8217;\u044b, \u0432 boost \u0431\u044b\u043b\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f protect, \u043c\u0430\u0441\u043a\u0438\u0440\u0443\u044e\u0449\u0430\u044f \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (bind \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u0441\u0432\u043e\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e type traits std::is_placeholder \u0438 std::is_bind_expression).<br \/>  \u041f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u0432 C++11 \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0435 \u0432\u043e\u0448\u043b\u0430 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043d\u043e \u0435\u0451 \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e \u043c\u043e\u0442\u0438\u0432\u0430\u043c. \u0421\u043f\u0430\u0441\u0438\u0431\u043e Stack Overflow, \u0432\u0441\u0451 \u0443\u0436\u0435 \u0443\u043a\u0440\u0430\u0434\u0435\u043d\u043e \u0434\u043e \u043d\u0430\u0441.  <\/p>\n<pre><code class=\"cpp\">template&lt;typename T&gt; \/\/ \u0433\u0434\u0435 T - \u043d\u0435\u043a\u0438\u0439 \u043a\u043b\u0430\u0441\u0441 - \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 bind-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f struct protect_wrapper : T {     protect_wrapper(const T& t) : T(t) {}     protect_wrapper(T&& t) : T(std::move(t)) {}     \/\/ \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440() \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d };  \/\/ \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 bind - \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u043a\u0430\u043a \u0435\u0441\u0442\u044c template&lt;typename T&gt; typename std::enable_if&lt; !std::is_bind_expression&lt; typename std::decay&lt;T&gt;::type &gt;::value,                 T&& &gt;::type protect(T&& t) {     return std::forward&lt;T&gt;(t); }  \/\/ \u0435\u0441\u043b\u0438 \u044d\u0442\u043e bind - \u0437\u0430\u0432\u0435\u0440\u043d\u0451\u043c \u0432 protect_wrapper template&lt;typename T&gt; typename std::enable_if&lt; std::is_bind_expression&lt; typename std::decay&lt;T&gt;::type &gt;::value,                 protect_wrapper&lt;typename std::decay&lt;T&gt;::type &gt; &gt;::type protect(T&& t) {     return protect_wrapper&lt;typename std::decay&lt;T&gt;::type &gt;(std::forward&lt;T&gt;(t)); } <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c <code>bind(foo, protect(bind(bar, _1)), _1)(x)<\/code> \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u044c, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f foo \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0434\u0440\u0443\u0433\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e bar(_1), \u0430 \u043d\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f bar(x).<\/p>\n<p>  protect(bind(&#8230;)) \u2014 \u044d\u0442\u043e \u0438\u0434\u0438\u043e\u043c\u0430, \u0438 \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0445 \u0441\u043a\u043e\u0431\u043e\u043a, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044e:  <\/p>\n<pre><code class=\"cpp\">template&lt;class... Args&gt; auto probind(Args... args) -&gt; decltype(protect(bind(args...))) { return protect(bind(args...)); } <\/code><\/pre>\n<p>  \u041d\u0430 C++03 \u043e\u043d\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0430 \u0431\u044b \u0431\u043e\u043b\u0435\u0435 \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u043e \u2014 \u0431\u0435\u0437 \u0432\u0430\u0440\u0438\u0430\u0434\u0438\u043a\u043e\u0432, \u0431\u0435\u0437 \u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0438\u043f\u043e\u0432. \u041d\u043e, \u044f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u0441\u0435 \u0443\u0436\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043b\u0438 \u0441\u0432\u043e\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u044b? \u0410 \u043a\u0442\u043e \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043b, \u043f\u0438\u0448\u0438\u0442\u0435 protect(bind(&#8230;..)).<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e, \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 probind \u043d\u0430\u0441 \u043d\u0435 \u0441\u043f\u0430\u0441\u0451\u0442.  <\/p>\n<pre><code class=\"cpp\">void run(char cx, char cy) {   getconfig(cx,     probind(getconfig, cy,       probind(entry, _1, _2, \/\/ \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0434\u0435\u043b\u0430\u0442\u044c? getconfig \u0445\u043e\u0447\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c!         probind(finish, cx, cy, _1) \/\/ \u0437\u0434\u0435\u0441\u044c \u0432\u0441\u0451 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e: \u043e\u0442\u0434\u0430\u0434\u0438\u043c \u0432 entry \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0435 \u0441 \u043e\u0434\u043d\u0438\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c       )     )   ); } <\/code><\/pre>\n<p>  \u041d\u0430\u0434\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u0434\u0438\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043d\u0430\u0434\u043e \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u044f\u043c\u043e \u0441\u0435\u0439\u0447\u0430\u0441, \u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u0430\u043d\u0435\u0442 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f.<br \/>  \u0411\u0435\u0437 protect \u2014 \u043e\u0431\u0430 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u044f\u0442\u0441\u044f \u0441\u0440\u0430\u0437\u0443, \u0441 protect \u2014 \u043e\u0431\u0430 \u0441\u0442\u0430\u043d\u0443\u0442 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438.<\/p>\n<p>  \u0412\u043e\u043e\u0431\u0449\u0435, bind, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 bind \u2014 \u044d\u0442\u043e \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430. \u041d\u0430 \u0442\u043e\u043c \u0436\u0435 StackOverflow \u043d\u0430\u0440\u043e\u0434 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0447\u0430\u0441\u0442\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438 \u043f\u0440\u043e \u00abbind return bind\u00bb, \u0438 \u0434\u0430\u0451\u0442 \u0447\u0430\u0441\u0442\u043d\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b. \u0410 \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u0438\u0437\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438\u2026<\/p>\n<h5>\u0422\u0440\u0435\u0442\u0438\u0439 \u0442\u0440\u044e\u043a<\/h5>\n<p>  \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0443\u0442\u0435\u0439.<\/p>\n<p>  \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0435\u0441\u0442\u043d\u044b\u0439 \u043a\u0430\u0440\u0440\u0438\u043d\u0433, \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u043e\u0442\u043e\u043c \u0432 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0451 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u2026 \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442, \u043c\u044f\u0433\u043a\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u043e.<\/p>\n<p>  \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u043f\u043e\u0434 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u0440\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e entry  <\/p>\n<pre><code class=\"cpp\">struct curried_entry_t {   template&lt;class Y, class K&gt;   auto operator()(Y&& y, K&& k) const -&gt; decltype( probind(entry,_1,y,k) ) { return probind(entry,_1,y,k); } };  void run(char cx, char cy) {   getconfig(cx,     probind(getconfig, cy,       bind(curried_entry, _1, \/\/ getconfig(cx, H) \u0432\u044b\u0437\u043e\u0432\u0435\u0442 H(x) = probind(getconfig,cy,bind(curried_entry,x,F))         probind(finish, cx, cy, _1)       )     )   ); } <\/code><\/pre>\n<p>  \u2026 \u0438\u043b\u0438, \u0445\u043e\u0442\u044f \u0431\u044b, \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440:  <\/p>\n<pre><code class=\"cpp\">struct curry_binary_t {   template&lt;class E, class X, class K&gt;   auto operator(E&& e, X&& x) const -&gt; decltype( probind(e,x,_1) ) { return probind(e,x,_1); } } curry_binary;  void run(char cx, char cy) {   getconfig(cx,     probind(getconfig, cy,       bind(curry_binary,         probind(entry, _1, _2,           probind(finish, cx, cy, _1)         ),         _1 \/\/ getconfig(x,H) \u0432\u044b\u0437\u043e\u0432\u0435\u0442 H(x) \u0438 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442 x \u0441\u044e\u0434\u0430       )     )   ); } <\/code><\/pre>\n<p>  \u0412-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u043f\u0440\u0438\u0431\u0435\u0433\u043d\u0435\u043c \u043a \u0442\u0440\u044e\u043a\u0443, \u043f\u043e\u0445\u043e\u0436\u0435\u043c\u0443 \u043d\u0430 \u0442\u0440\u044e\u043a \u0441 protect: \u043f\u043e\u043c\u0435\u0448\u0430\u0435\u043c bind&#8217;\u0443 \u0440\u0430\u043d\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u043e\u0434\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443.  <\/p>\n<pre><code class=\"cpp\">\/\/ \u043c\u0435\u0441\u0442\u043e\u0438\u043c\u0435\u043d\u0438\u044f \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0430 _dN \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u0445 \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438 _pass_ struct _d1_t {} const _d1;  auto _pass_(_d1_t) -&gt; decltype(_1) { return _1; } struct _d2_t {} const _d2;  auto _pass_(_d2_t) -&gt; decltype(_2) { return _2; } struct _d3_t {} const _d3;  auto _pass_(_d3_t) -&gt; decltype(_3) { return _3; } \/\/ \u0438 \u0442.\u0434. \u0434\u043e _d9 template&lt;class T&gt; auto _pass_(T&& t) -&gt; T&& { return t; } \/\/ \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u0435\u0441\u0442\u044c  struct partial_t {   \/\/TODO: \u043d\u0430\u0433\u0435\u043d\u0435\u0440\u0438\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u043d\u0430 \u0432\u0441\u0435 \u0440\u0430\u0437\u0443\u043c\u043d\u044b\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 (\u0438\u043b\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u0432\u0430\u0440\u0438\u0430\u0434\u0438\u043a\u0430\u0445)    template&lt;class F&gt;   auto operator()(F&& f) const -&gt; decltype( probind(f) )   { return probind(f); }    template&lt;class F, class T1&gt;   auto operator()(F&& f, T1&& t1) const -&gt; decltype( probind(f, _pass_(t1)) )   { return probind(f, _pass_(t1)); }    template&lt;class F, class T1, class T2&gt;   auto operator()(F&& f, T1&& t1, T2&& t2) const -&gt; decltype( probind(f, _pass_(t1), _pass_(t2)) )   { return probind(f, _pass_(t1), _pass_(t2)); } } const partial;  void run(char cx, char cy) {   getconfig(cx,     probind(getconfig, cy,       bind(partial,         probind(entry, _1, _2,           probind(finish, cx, cy, _1)         ), \/\/ \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 F - \u043d\u0435\u043a\u0430\u044f \u0434\u0432\u0443\u0445\u043c\u0435\u0441\u0442\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f...         _1,    \/\/ \u043f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u043e\u0439 getconfig(cx, H) --&gt; H(x)         _d1, \/\/ \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b\u0437\u043e\u0432\u0435\u0442 getconfig(cy,E) --&gt; E(y)       )     )   ); } <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043a \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0439 <b>protect<\/b>, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043d\u0430\u043c <b>partial<\/b>, \u2014 \u0438 \u0441\u043c\u043e\u0433\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0445 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f\u0445!<\/p>\n<p>  \u041d\u0443 \u0430 \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u0448\u043d\u043e\u0439 \u043b\u0435\u0441\u0435\u043d\u043a\u0438, \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u0432 \u0441\u0442\u043e\u043b\u0431\u0438\u043a  <\/p>\n<pre><code class=\"cpp\">void run_(char cx, char cy) {   \/\/ \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u0438: \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f   auto g = probind(getconfig, cx, _1);  \/\/ void(K)   auto h = probind(getconfig, cy, _1);  \/\/ void(K)   auto e = probind(entry, _1, _2, _3); \/\/ void(ABCD,ABCD,K)   \/\/ \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a - \u0431\u0435\u0437 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f   auto f = probind(finish, cx, cy, _1);    \/\/ \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438   auto fe   = probind(e,_1,_2,f); \/\/auto feh  = probind(h, bind(curried_entry,_1,f)); \/\/auto feh  = probind(h, bind(curry_binary,fe,_1));   auto feh  = probind(h, bind(partial, fe, _d1, _1));   auto fegh = probind(g, feh);    \/\/ \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c   fegh(); } <\/code><\/pre>\n<p>  \u041d\u0443 \u0447\u0442\u043e, \u0438\u0441\u043f\u044b\u0442\u0430\u0435\u043c?  <\/p>\n<pre><code class=\"cpp\">int main() {   vector&lt;char&gt; abcd = { 'a','b','c','d','e' };   for(auto x : abcd)     for(auto y : abcd)       run_1(x,y); } <\/code><\/pre>\n<h5>\u041f\u043e\u043b\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b<\/h5>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0432\u0441\u0451 \u0432 \u043a\u0443\u0447\u0443<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;functional&gt; using namespace std; using namespace std::placeholders;  struct A { int      foo() { return 1; } } const a; struct B { unsigned foo() { return 2; } } const b; struct C { long     foo() { return 3; } } const c; struct D { double   foo() { return 4; } } const d;  \/\/ \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043f\u0435\u0440\u0432\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0439 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f  struct getconfig_t {     template&lt;class K&gt; \/\/ \u0433\u0434\u0435 K \u0438\u043c\u0435\u0435\u0442 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443 void f(ABCD)     void operator()(char t, K kont) const     {         cout &lt;&lt; &quot;getconfig(&quot; &lt;&lt; t &lt;&lt; &quot;) &quot;;         switch(t)         {         case 'a': kont(A()); break;         case 'b': kont(B()); break;         case 'c': kont(C()); break;         case 'd': kont(D()); break;         default:  cout &lt;&lt; &quot;bad type&quot; &lt;&lt; endl; break; \/\/ \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 :)         }     } } const getconfig;  struct entry_t \/\/ e(X,Y,K), \u0433\u0434\u0435 X \u0438 Y = A\/B\/C\/D, \u0430 K \u0438\u043c\u0435\u0435\u0442 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443 f(N) {     template&lt;class X, class Y, class K&gt;     void operator()(X&& x, Y&& y, K&& kont) const     {         cout &lt;&lt; &quot;entry(...) &quot;;         kont(x.foo()*10 + y.foo());     } } const entry;  struct finish_t \/\/ void f(N) {     template&lt;class N&gt; void report(char cx, char cy, const char* type, N value) const     {         cout &lt;&lt; &quot;finish() : &quot;;         cout &lt;&lt; cx &lt;&lt; &quot;+&quot; &lt;&lt; cy &lt;&lt; &quot; = &quot; &lt;&lt; type &lt;&lt; &quot; &quot; &lt;&lt; value &lt;&lt; endl;     }      void operator()(char cx, char cy, int           n) const { report(cx,cy, &quot;int   &quot;, n); }     void operator()(char cx, char cy, unsigned      n) const { report(cx,cy, &quot;uint  &quot;, n); }     void operator()(char cx, char cy, long          n) const { report(cx,cy, &quot;long  &quot;, n); }     void operator()(char cx, char cy, unsigned long n) const { report(cx,cy, &quot;ulong &quot;, n); }     void operator()(char cx, char cy, double        n) const { report(cx,cy, &quot;double&quot;, n); } } const finish;   \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ \/\/ \u043f\u0440\u043e\u0442\u0435\u043a\u0442\u043e\u0440 bind-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439  template&lt;typename T&gt; struct protect_wrapper : T {     protect_wrapper(const T& t) : T(t) {}     protect_wrapper(T&& t) : T(std::move(t)) {} };   template&lt;typename T&gt; typename std::enable_if&lt; !std::is_bind_expression&lt; typename std::decay&lt;T&gt;::type &gt;::value,                 T&& &gt;::type protect(T&& t) {     return std::forward&lt;T&gt;(t); }  template&lt;typename T&gt; typename std::enable_if&lt; std::is_bind_expression&lt; typename std::decay&lt;T&gt;::type &gt;::value,                 protect_wrapper&lt;typename std::decay&lt;T&gt;::type &gt; &gt;::type protect(T&& t) {     return protect_wrapper&lt;typename std::decay&lt;T&gt;::type &gt;(std::forward&lt;T&gt;(t)); }   template&lt;class... Args&gt; auto probind(Args... args) -&gt; decltype(protect(bind(args...))) { return protect(bind(args...)); }   \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ \/\/ \u043a\u0430\u0440\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f entry  struct curried_entry_t \/\/ E1 e(Y,K), \u0433\u0434\u0435 E1 = void e1(X) {     template&lt;class Y, class K&gt;     auto operator()(Y&& y, K&& k) const -&gt; decltype( probind(entry,_1,y,k) ) { return probind(entry,_1,y,k); } } const curried_entry;   \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ \/\/ \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0434\u0432\u0443\u0445\u043c\u0435\u0441\u0442\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438  struct curry_binary_t {     template&lt;class F, class X&gt;     auto operator()(F&& f, X&& x) const -&gt; decltype( probind(f,x,_1) ) { return probind(f,x,_1); } } const curry_binary;   \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ \/\/ \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0439  struct _d1_t {} const _d1;  auto _pass_(_d1_t) -&gt; decltype(_1) { return _1; } struct _d2_t {} const _d2;  auto _pass_(_d2_t) -&gt; decltype(_2) { return _2; } struct _d3_t {} const _d3;  auto _pass_(_d3_t) -&gt; decltype(_3) { return _3; } template&lt;class T&gt; auto _pass_(T&& t) -&gt; T&& { return t; }  struct partial_t {     template&lt;class F&gt;     auto operator()(F&& f) const -&gt; decltype( probind(f) )     { return probind(f); }      template&lt;class F, class T1&gt;     auto operator()(F&& f, T1&& t1) const -&gt; decltype( probind(f, _pass_(t1)) )     { return probind(f, _pass_(t1)); }      template&lt;class F, class T1, class T2&gt;     auto operator()(F&& f, T1&& t1, T2&& t2) const -&gt; decltype( probind(f, _pass_(t1), _pass_(t2)) )     { return probind(f, _pass_(t1), _pass_(t2)); } } const partial;   struct binder_t {     template&lt;class F, class... Args&gt;     auto operator()(F&& f, Args... args) const -&gt; decltype(bind(f,args...)) { return bind(f,args...); } } const binder;    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ \/\/ \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u0435\u043c!  void run_1(char cx, char cy) {     \/\/ \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u0438: \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f     auto g = probind(getconfig, cx, _1);  \/\/ void(K)     auto h = probind(getconfig, cy, _1);  \/\/ void(K)     auto e = probind(entry, _1, _2, _3); \/\/ void(ABCD,ABCD,K)     \/\/ \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a - \u0431\u0435\u0437 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f     auto f = probind(finish, cx, cy, _1);      \/\/ \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438     auto fe   = probind(e,_1,_2,f);   \/\/auto feh  = probind(h, bind(curried_entry, _1, f));   \/\/auto feh  = probind(h, bind(curry_binary, fe, _1));     auto feh  = probind(h, bind(partial, fe, _d1, _1));     auto fegh = probind(g, feh);      \/\/ \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c     fegh(); }  void run_2(char cx, char cy) {   getconfig(cx,     probind(getconfig, cy,       bind(partial,         probind(entry, _1, _2,           probind(finish, cx, cy, _1)         ),         _1, _d1       )     )   ); }  \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ \/\/ \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0451 \u0441\u043e \u0432\u0441\u0435\u043c\u0438!  int main() {     vector&lt;char&gt; abcd = { 'a','b','c','d','e' };     for(auto x : abcd)         for(auto y : abcd)             run_1(x,y); } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<h5>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/h5>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u043a\u0440\u044b\u0442\u044b\u0439 \u0442\u0435\u043a\u0441\u0442<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code>getconfig(a) getconfig(a) entry(...) finish() : a+a = int    11 getconfig(a) getconfig(b) entry(...) finish() : a+b = uint   21 getconfig(a) getconfig(c) entry(...) finish() : a+c = long   31 getconfig(a) getconfig(d) entry(...) finish() : a+d = double 41 getconfig(a) getconfig(e) bad type getconfig(b) getconfig(a) entry(...) finish() : b+a = uint   12 getconfig(b) getconfig(b) entry(...) finish() : b+b = uint   22 getconfig(b) getconfig(c) entry(...) finish() : b+c = ulong  32 getconfig(b) getconfig(d) entry(...) finish() : b+d = double 42 getconfig(b) getconfig(e) bad type getconfig(c) getconfig(a) entry(...) finish() : c+a = long   13 getconfig(c) getconfig(b) entry(...) finish() : c+b = ulong  23 getconfig(c) getconfig(c) entry(...) finish() : c+c = long   33 getconfig(c) getconfig(d) entry(...) finish() : c+d = double 43 getconfig(c) getconfig(e) bad type getconfig(d) getconfig(a) entry(...) finish() : d+a = double 14 getconfig(d) getconfig(b) entry(...) finish() : d+b = double 24 getconfig(d) getconfig(c) entry(...) finish() : d+c = double 34 getconfig(d) getconfig(d) entry(...) finish() : d+d = double 44 getconfig(d) getconfig(e) bad type getconfig(e) bad type getconfig(e) bad type getconfig(e) bad type getconfig(e) bad type getconfig(e) bad type <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<h4>To be continued&#8230;<\/h4>\n<p>  \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043c\u044b \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e\u0435:  <\/p>\n<ol>\n<li>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 return<\/li>\n<li>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u0435 \u0432 out-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440<\/li>\n<li>\u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c \u0441 \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0433\u043b\u0443\u0431\u0438\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u2014 \u044d\u0442\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0440\u0451\u0445\u043c\u0435\u0441\u0442\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e entry(X,Y,Z, Kont)<\/li>\n<\/ol>\n<p>  \u0422\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u043c\u044b \u043d\u0435 \u0441\u0442\u0430\u043b\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0440\u0430\u0441\u0438\u0432\u043e\u0441\u0442\u0438, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0432\u0435\u0435\u0440 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439 (\u0432 \u0441\u0442\u0438\u043b\u0435 &gt;&gt;= \u0438\u043b\u0438 do-\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0425\u0430\u0441\u043a\u0435\u043b\u043b\u0430, \u0433\u0434\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0441\u0443\u0442\u044c \u043c\u043e\u043d\u0430\u0434\u0430).<br \/>  \u0418 \u0443\u0436 \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u043d\u0435 \u0434\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0434\u043e \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0436\u043d\u043e\u0439 \u0432\u0435\u0449\u0438, \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0445\u043e\u0434\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0441\u043e\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c, \u2014 \u0442\u043e, \u0447\u0435\u043c \u043a\u0430\u043a \u0440\u0430\u0437 CPS \u0441\u043b\u0430\u0432\u0438\u0442\u0441\u044f.<\/p>\n<p>  \u041d\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0442\u0430\u0442\u044c\u044f \u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f\u0445, \u2014 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u044d\u0442\u0443 \u0442\u0435\u043c\u0443.      \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/232979\/\"> http:\/\/habrahabr.ru\/post\/232979\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">     \t\u041d\u0430\u043c\u0435\u0434\u043d\u0438 \u043d\u0430 RSDN \u0431\u044b\u043b \u0437\u0430\u0434\u0430\u043d \u0442\u0430\u043a\u043e\u0439 \u0432\u043e\u043f\u0440\u043e\u0441:<br \/>  \u041f\u0443\u0441\u0442\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0430\u044f \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0439 \u0442\u0438\u043f  <\/p>\n<pre><code class=\"cpp\">class Base { virtual int foo() const = 0; }; class A : public Base { int foo() const { return 1; } }; class B : public Base { int foo() const { return 2; } }; class C : public Base { int foo() const { return 3; } }; class D : public Base { int foo() const { return 4; } };  Base* getconfig(char cfg) \/\/ \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043a\u0430 \u043e\u0442\u0432\u043b\u0435\u043a\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0443\u0431\u043e\u0440\u043a\u0443 \u043c\u0443\u0441\u043e\u0440\u0430 {   switch(cfg)   {   case 'a': return new A();   case 'b': return new B();   case 'c': return new C();   case 'd': return new D();   default: throw std::invalid_argument(&quot;bad type&quot;);   } } <\/code><\/pre>\n<p>  \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0430\u044f \u0435\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b  <\/p>\n<pre><code class=\"cpp\">int entry(Base* x, Base* y) { return x-&gt;foo()*10 + y-&gt;foo(); } <\/code><\/pre>\n<p>  \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a  <\/p>\n<pre><code class=\"cpp\">void run(char cx, char cy) { std::cout &lt;&lt; cx &lt;&lt; cy &lt;&lt; &quot; : &quot; &lt;&lt; entry(getconfig(cx), getconfig(cy)) &lt;&lt; std::endl; } <\/code><\/pre>\n<p>  \u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u043f\u0440\u043e\u0442\u0430\u0449\u0438\u0442\u044c \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u0438\u0437\u043c \u043d\u0430 \u0441\u0442\u0430\u0434\u0438\u044e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438?  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-232979","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/232979","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=232979"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/232979\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=232979"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=232979"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=232979"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}