{"id":279232,"date":"2016-04-27T20:15:04","date_gmt":"2016-04-27T16:15:04","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=279232"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=279232","title":{"rendered":"C++ pattern matching"},"content":{"rendered":"\n<p>\u041d\u0435\u0442 \u043d\u0443\u0436\u0434\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0447\u0435\u043c \u0445\u043e\u0440\u043e\u0448 pattern matching. \u0422\u0430\u043a \u043a\u0430\u043a \u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432 \u0421++ \u043d\u0435\u0442.<br \/>  \u0411\u0435\u0437 \u043d\u0435\u0433\u043e \u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438, \u0447\u0430\u0441\u0442\u043e \u043e\u0431\u0440\u0430\u0441\u0442\u0430\u0435\u0442 \u043b\u0435\u0441\u0430\u043c\u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0433\u043e \u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430.<br \/>  \u0418\u0442\u0430\u043a \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0441\u043f\u043e\u0441\u043e\u0431 \u043d\u0435\u043a\u043e\u0435\u0433\u043e \u043f\u043e\u0434\u043e\u0431\u0438\u044f pattern matching`\u0430 \u0434\u043b\u044f \u0421++14 (\u0441\u043a\u043e\u0440\u0435\u0435 \u0434\u0430\u0436\u0435 type matching&#8217;a), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 50 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430, \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043a\u0440\u043e\u0441\u0441-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043d\u044b\u0439.<\/p>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f: <a href=\"http:\/\/coliru.stacked-crooked.com\/a\/6066e8c3d87e31eb\">http:\/\/coliru.stacked-crooked.com\/a\/6066e8c3d87e31eb<\/a><\/p>\n<p>  <\/p>\n<pre><code>template&lt;class T&gt; decltype(auto) test(T&amp; value) {     return match(value         ,[](std::string value)    { cout &lt;&lt; &quot;This is string&quot;; return value + &quot; Hi!&quot;; }         ,[](int i)                { cout &lt;&lt; &quot;This is int&quot;;    return i * 100; }         ,[](auto a)               { cout &lt;&lt; &quot;This is default&quot;;return nullptr; }     ); }<\/code><\/pre>\n<p>  <\/p>\n<p>compile-time \u0423\u0441\u043b\u043e\u0432\u0438\u044f: <a href=\"http:\/\/coliru.stacked-crooked.com\/a\/ccb13547b04ce6ad\">http:\/\/coliru.stacked-crooked.com\/a\/ccb13547b04ce6ad<\/a><\/p>\n<p>  <\/p>\n<pre><code>match(true_type{}          ,[](bool_constant&lt; T::value == 10 &gt;)                        { cout &lt;&lt; &quot;1&quot; ; }          ,[](bool_constant&lt; (T::value == 20 &amp;&amp; sizeof...(Args)&gt;4) &gt;) { cout &lt;&lt; &quot;2&quot; ; }     );<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0442\u0438\u043f: <a href=\"http:\/\/coliru.stacked-crooked.com\/a\/0a8788d026008b4b\">http:\/\/coliru.stacked-crooked.com\/a\/0a8788d026008b4b<\/a><\/p>\n<p>  <\/p>\n<pre><code>auto t = match(true_type{}            ,[](is_same_t&lt;T, int&gt;) -&gt; type_holder&lt;short&gt;  { return{}; }            ,[](auto)              -&gt; type_holder&lt;T&gt;      { return{}; }          );  using I = typename decltype(t)::type;              I i = 1000000;<\/code><\/pre>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2>\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/h2>\n<p>  <\/p>\n<pre><code>match(value                    \/\/ &lt;- \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0442\u0438\u043f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f      ,[](std::string value)    { \/* \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 std::string *\/ }               ,[](int i)                { \/* \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432  *\/ return i+100; }       ,[](auto a)               { \/* \u0410\u043d\u0430\u043b\u043e\u0433 default: \u0432 switch *\/ }      ); <\/code><\/pre>\n<p>  <\/p>\n<h2>\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430:<\/p>\n<p>  <\/p>\n<pre><code>namespace details {     template&lt;class T, class Case, class ...OtherCases&gt;     decltype(auto) match_call(const Case&amp; _case, T&amp;&amp; value, std::true_type, const OtherCases&amp;...) {         return _case(std::forward&lt;T&gt;(value));     }      template&lt;class T, class Case, class ...OtherCases&gt;     decltype(auto) match_call(const Case&amp; _case, T&amp;&amp; value, std::false_type, const OtherCases&amp;...) {         return match(std::forward&lt;T&gt;(value), other...);     } }  template&lt;class T, class Case, class ...Cases&gt; decltype(auto) match(T&amp;&amp; value, const Case&amp; _case, const Cases&amp;... cases) {     using namespace std;     using args = typename FunctionArgs&lt;Case&gt;::args;               \/\/ &lt;- \u042d\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e!     using arg = tuple_element_t&lt;0, args&gt;;     using match = is_same&lt;decay_t&lt;arg&gt;, decay_t&lt;T&gt;&gt;;     return details::match_call(_case, std::forward&lt;T&gt;(value), match{}, cases...); }  \/\/ \u044d\u0442\u043e \u0434\u043b\u044f default template&lt;class T, class Case&gt; decltype(auto) match(T&amp;&amp; value, const Case&amp; _case) {     return _case(std::forward&lt;T&gt;(value)); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>match<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>value<\/code> \u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043b\u044f\u043c\u0431\u0434 (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043b\u0443\u0436\u0430\u0442 case&#8217;\u043c\u0438). \u0423 \u043a\u0430\u0436\u0434\u043e\u0439 \u043b\u044f\u043c\u0431\u0434\u044b \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>FunctionArgs<\/code> \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0438\u043f \u044d\u0442\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430. \u0417\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c \u043b\u044f\u043c\u0431\u0434\u0430\u043c \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u0443 \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0442\u0438\u043f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043b\u044f\u043c\u0431\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c generic \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0438\u043f \u0435\u0451 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f. \u041e\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f. \u0415\u0441\u043b\u0438 \u043e\u043d\u0430 \u043d\u0435 generic, \u0438 \u0442\u0438\u043f \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0434\u0430\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 (\u043f\u0440\u0430\u0432\u0434\u0430 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u0442\u0438\u043f\u0443).<\/p>\n<p>  <\/p>\n<p><em>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043a\u0430\u043a \u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c generic \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043b\u044f\u043c\u0431\u0434\u0430 \u0438\u043b\u0438 \u043d\u0435\u0442, \u043d\u043e \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u2014 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e.<\/em><\/p>\n<p>  <\/p>\n<p>FunctionArgs \u2014 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f <a href=\"http:\/\/stackoverflow.com\/a\/27867127\/1559666\">http:\/\/stackoverflow.com\/a\/27867127\/1559666<\/a> :<\/p>\n<p>  <\/p>\n<pre><code>template &lt;typename T&gt; struct FunctionArgs : FunctionArgs&lt;decltype(&amp;T::operator())&gt; {};  template &lt;typename R, typename... Args&gt; struct FunctionArgsBase{     using args  = std::tuple&lt;Args...&gt;;     using arity = std::integral_constant&lt;unsigned, sizeof...(Args)&gt;;     using result = R; };  template &lt;typename R, typename... Args&gt; struct FunctionArgs&lt;R(*)(Args...)&gt; : FunctionArgsBase&lt;R, Args...&gt; {}; template &lt;typename R, typename C, typename... Args&gt; struct FunctionArgs&lt;R(C::*)(Args...)&gt; : FunctionArgsBase&lt;R, Args...&gt; {}; template &lt;typename R, typename C, typename... Args&gt; struct FunctionArgs&lt;R(C::*)(Args...) const&gt; : FunctionArgsBase&lt;R, Args...&gt; {};<\/code><\/pre>\n<p>  <\/p>\n<h1>P.S.<\/h1>\n<p>  <\/p>\n<p>\u0414\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 <a href=\"https:\/\/github.com\/solodon4\/Mach7\">https:\/\/github.com\/solodon4\/Mach7<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 pattern matching (\u043c\u043e\u0436\u043d\u043e \u0434\u0430\u0436\u0435 \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e \u0432 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043b\u043d\u043e\u0439 \u043c\u0435\u0440\u0435). \u041d\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441, \u043e\u0431\u0438\u043b\u0438\u0435 \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432, \u0435\u0451 \u043e\u0431\u044a\u0451\u043c, \u0438 \u0442\u043e \u0447\u0442\u043e \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043e\u043d\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e\u2026 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043e\u0442\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438 \u0430\u0432\u0442\u043e\u0440\u0430 \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u044d\u0442\u043e\u0433\u043e \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430\u2026<br \/>  \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0434\u0435\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0432\u0435\u0442\u043b\u043e\u0435 \u0431\u0443\u0434\u0443\u0449\u0435\u0435 \u0432 \u043b\u0438\u0446\u0435 \u0441++23 \u0430 \u043c\u043e\u0436\u0435\u0442 \u0438 \u0441++20 \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 pattern matching&#8217;a \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u044f\u0437\u044b\u043a\u0430. <\/p>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u043e\u043c (\u0434\u043b\u044f \u043a\u043e\u043f\u0438-\u043f\u0430\u0441\u0442\u0430)<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code>\/* std::string s = &quot;12&quot;; cout &lt;&lt; match(s     ,[](int&amp; i) { return &quot;int&quot;; }     ,[](bool&amp; b) { return &quot;bool&quot;; }     ,[](std::string&amp; s) -&gt; auto&amp; { s += &quot; GAV&quot;; return s; }     ,[](auto j) { cout &lt;&lt; &quot;default one&quot;; return j; } ); *\/  #include &lt;tuple&gt;  template &lt;typename T&gt; struct FunctionArgs : FunctionArgs&lt;decltype(&amp;T::operator())&gt; {};  template &lt;typename R, typename... Args&gt; struct FunctionArgsBase{     using args  = std::tuple&lt;Args...&gt;;     using arity = std::integral_constant&lt;unsigned, sizeof...(Args)&gt;;     using result = R; };  template &lt;typename R, typename... Args&gt; struct FunctionArgs&lt;R(*)(Args...)&gt; : FunctionArgsBase&lt;R, Args...&gt; {}; template &lt;typename R, typename C, typename... Args&gt; struct FunctionArgs&lt;R(C::*)(Args...)&gt; : FunctionArgsBase&lt;R, Args...&gt; {}; template &lt;typename R, typename C, typename... Args&gt; struct FunctionArgs&lt;R(C::*)(Args...) const&gt; : FunctionArgsBase&lt;R, Args...&gt; {};  \/\/ forward declarations template&lt;class T, class Case, class ...Cases&gt; decltype(auto) match(T&amp;&amp; value, const Case&amp; _case, const Cases&amp;... cases); template&lt;class T, class Case&gt; decltype(auto) match(T&amp;&amp; value, const Case&amp; _case);  namespace details {     template&lt;class T, class Case, class ...OtherCases&gt;     decltype(auto) match_call(const Case&amp; _case, T&amp;&amp; value, std::true_type, const OtherCases&amp;... other) {         return _case(std::forward&lt;T&gt;(value));     }      template&lt;class T, class Case, class ...OtherCases&gt;     decltype(auto) match_call(const Case&amp; _case, T&amp;&amp; value, std::false_type, const OtherCases&amp;... other) {         return match(std::forward&lt;T&gt;(value), other...);     } }  template&lt;class T, class Case, class ...Cases&gt; decltype(auto) match(T&amp;&amp; value, const Case&amp; _case, const Cases&amp;... cases) {     using namespace std;     using args = typename FunctionArgs&lt;Case&gt;::args;     using arg = tuple_element_t&lt;0, args&gt;;     using match = is_same&lt;decay_t&lt;arg&gt;, decay_t&lt;T&gt;&gt;;     return details::match_call(_case, std::forward&lt;T&gt;(value), match{}, cases...); }  \/\/ the last one is default template&lt;class T, class Case&gt; decltype(auto) match(T&amp;&amp; value, const Case&amp; _case) {     return _case(std::forward&lt;T&gt;(value)); }<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"clear\"><\/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=\"https:\/\/habrahabr.ru\/post\/282630\/\"> https:\/\/habrahabr.ru\/post\/282630\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<p>\u041d\u0435\u0442 \u043d\u0443\u0436\u0434\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0447\u0435\u043c \u0445\u043e\u0440\u043e\u0448 pattern matching. \u0422\u0430\u043a \u043a\u0430\u043a \u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432 \u0421++ \u043d\u0435\u0442.<br \/>  \u0411\u0435\u0437 \u043d\u0435\u0433\u043e \u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438, \u0447\u0430\u0441\u0442\u043e \u043e\u0431\u0440\u0430\u0441\u0442\u0430\u0435\u0442 \u043b\u0435\u0441\u0430\u043c\u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0433\u043e \u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430.<br \/>  \u0418\u0442\u0430\u043a \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0441\u043f\u043e\u0441\u043e\u0431 \u043d\u0435\u043a\u043e\u0435\u0433\u043e \u043f\u043e\u0434\u043e\u0431\u0438\u044f pattern matching`\u0430 \u0434\u043b\u044f \u0421++14 (\u0441\u043a\u043e\u0440\u0435\u0435 \u0434\u0430\u0436\u0435 type matching&#8217;a), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 50 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430, \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043a\u0440\u043e\u0441\u0441-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043d\u044b\u0439.<\/p>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f: <a href=\"http:\/\/coliru.stacked-crooked.com\/a\/6066e8c3d87e31eb\">http:\/\/coliru.stacked-crooked.com\/a\/6066e8c3d87e31eb<\/a><\/p>\n<p>  <\/p>\n<pre><code>template&lt;class T&gt; decltype(auto) test(T&amp; value) {     return match(value         ,[](std::string value)    { cout &lt;&lt; &quot;This is string&quot;; return value + &quot; Hi!&quot;; }         ,[](int i)                { cout &lt;&lt; &quot;This is int&quot;;    return i * 100; }         ,[](auto a)               { cout &lt;&lt; &quot;This is default&quot;;return nullptr; }     ); }<\/code><\/pre>\n<p>  <\/p>\n<p>compile-time \u0423\u0441\u043b\u043e\u0432\u0438\u044f: <a href=\"http:\/\/coliru.stacked-crooked.com\/a\/ccb13547b04ce6ad\">http:\/\/coliru.stacked-crooked.com\/a\/ccb13547b04ce6ad<\/a><\/p>\n<p>  <\/p>\n<pre><code>match(true_type{}          ,[](bool_constant&lt; T::value == 10 &gt;)                        { cout &lt;&lt; &quot;1&quot; ; }          ,[](bool_constant&lt; (T::value == 20 &amp;&amp; sizeof...(Args)&gt;4) &gt;) { cout &lt;&lt; &quot;2&quot; ; }     );<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0442\u0438\u043f: <a href=\"http:\/\/coliru.stacked-crooked.com\/a\/0a8788d026008b4b\">http:\/\/coliru.stacked-crooked.com\/a\/0a8788d026008b4b<\/a><\/p>\n<p>  <\/p>\n<pre><code>auto t = match(true_type{}            ,[](is_same_t&lt;T, int&gt;) -&gt; type_holder&lt;short&gt;  { return{}; }            ,[](auto)              -&gt; type_holder&lt;T&gt;      { return{}; }          );  using I = typename decltype(t)::type;              I i = 1000000;<\/code><\/pre>\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-279232","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/279232","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=279232"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/279232\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=279232"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=279232"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=279232"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}