{"id":326974,"date":"2022-01-10T08:42:41","date_gmt":"2022-01-10T08:42:41","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=326974"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=326974","title":{"rendered":"<span>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432 C++Next \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\" class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" alt=\"\" title=\"\" height=\"440\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/787\/377\/1d3\/7873771d3cf1e86047bf7136f1c263ab.png\" data-width=\"780\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f &#171;\u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f&#187; \u0438\u0437 \u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438:<\/p>\n<blockquote>\n<p>In computer science, <strong>reflective programming<\/strong> or <strong>reflection<\/strong> is the ability of a process to examine, introspect, and modify its own structure and behavior.<\/p>\n<\/blockquote>\n<p>\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0433\u043e\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0432\u0432\u043e\u0434\u0430 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 C++.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u043d\u0430 C++ \u0441 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0435\u0439 \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447, <strong>\u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c<\/strong> \u0435\u0433\u043e \u043d\u0430 \u0444\u043e\u0440\u043a\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0441 \u0440\u0430\u0431\u043e\u0447\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438.<\/p>\n<h2>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445<\/h2>\n<p>\u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445, \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0445\u0441\u044f \u0434\u043b\u044f \u0431\u044d\u043a\u0435\u043d\u0434\u0430, \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u043e\u0447\u0435\u043d\u044c \u043c\u043e\u0449\u043d\u0430\u044f. \u041f\u0430\u0440\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432:<\/p>\n<p>\u0412 \u044f\u0437\u044b\u043a\u0435 <strong>Python<\/strong> \u0432 run-time \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430; \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430; \u0432\u0441\u0435 \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u044b; \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432 \u043a\u043b\u0430\u0441\u0441; \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443, \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u043a\u043b\u0430\u0441\u0441 \u044d\u0442\u043e dict (\u0441 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0441\u0430\u0445\u0430\u0440\u043e\u043c), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u0443\u0433\u043e\u0434\u043d\u043e.<\/p>\n<p>\u0412 \u044f\u0437\u044b\u043a\u0435 <strong>Java<\/strong> \u0432 run-time \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430; \u0435\u0433\u043e \u043f\u043e\u043b\u044f, \u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b, \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b, \u0441\u0443\u043f\u0435\u0440\u043a\u043b\u0430\u0441\u0441\u044b; \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f \u043f\u043e \u0435\u0433\u043e \u0438\u043c\u0435\u043d\u0438; \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u043e \u0438\u043c\u0435\u043d\u0438; \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043a\u043b\u0430\u0441\u0441\u0430\u0445 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 Java Virtual Machine.<\/p>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435 &#8212; \u043a\u0430\u043a \u0440\u0430\u0437 \u0442\u043e, \u0447\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434 \u0441\u043b\u043e\u0432\u043e\u043c &#171;\u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f&#187;.<\/p>\n<h2>\u042d\u0440\u0437\u0430\u0446-\u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432 C++<\/h2>\n<p>\u0412 C++ \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u0443\u0441\u043e\u0447\u043a\u0438 &#171;\u044f\u0437\u044b\u043a\u043e\u0437\u043d\u0430\u043d\u0438\u044f&#187;, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043a\u043e\u0434\u0435 &#8212; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_enum\" rel=\"noopener noreferrer nofollow\">std::is_enum<\/a> (compile-time), <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/typeid\" rel=\"noopener noreferrer nofollow\">typeid<\/a> (run-time).<\/p>\n<p>\u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043d\u0435\u0441\u0442\u0438 \u043a \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438, \u043d\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0441\u043f\u0430\u0440\u0442\u0430\u043d\u0441\u043a\u0438\u0439 \u0438 \u0434\u043b\u044f \u0432\u0435\u043b\u0438\u043a\u0438\u0445 \u0441\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0439 \u043d\u0435 \u0433\u043e\u0434\u0435\u043d. \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0437\u043d\u0430\u0435\u0442 \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u043f\u0440\u0438\u0441\u043f\u043e\u0441\u043e\u0431\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0438.<\/p>\n<h4>\u041a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0442\u0438\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h4>\n<p>\u041a \u044d\u0442\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 <a href=\"https:\/\/developers.google.com\/protocol-buffers\" rel=\"noopener noreferrer nofollow\">protobuf<\/a> &#8212; \u043c\u043e\u0434\u043d\u044b\u0439 &#171;\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c&#187; \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u0412 <code>.proto<\/code>-\u0444\u0430\u0439\u043b\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (<code>message Person<\/code>), \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u043b\u044f C++ \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0435\u0439 \u043a\u043b\u0430\u0441\u0441 (<code>class Person<\/code>) \u0441 \u0433\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438\/\u0441\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438, \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0435\u0437 \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0430 \u0438\u043c\u0435\u043d\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<p>\u0421\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u0432 \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 (\u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c, \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u043e \u0441\u0435\u0442\u0438), \u0438\u043b\u0438 \u0432 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f).<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0443 \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043a\u043e\u0440\u044f\u0447\u0438\u0442\u044c \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e protobuf \u0443\u0436\u0435 \u043d\u0430\u0431\u0438\u043b \u0432\u0441\u0435 \u0448\u0438\u0448\u043a\u0438 \u0437\u0430 \u043d\u0435\u0433\u043e.<\/p>\n<h4>\u0410\u0434\u0441\u043a\u0438\u0435 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u044b<\/h4>\n<p>\u041a \u044d\u0442\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/www.boost.org\/doc\/libs\/1_67_0\/libs\/hana\/doc\/html\/index.html\" rel=\"noopener noreferrer nofollow\">Boost.Hana<\/a>. \u0414\u043b\u044f \u043d\u0435\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0443\u0436\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">struct Person {   BOOST_HANA_DEFINE_STRUCT(Person,     (std::string, name),     (int, age)   ); };<\/code><\/pre>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441 &#171;\u0440\u0430\u0441\u043a\u0440\u043e\u0435\u0442\u0441\u044f&#187; \u0438 \u0432\u0441\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442. \u041f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 &#171;\u0434\u0435\u043c\u043e\u0441\u0446\u0435\u043d\u0443&#187; &#8212; \u0432\u044b\u0436\u0438\u043c\u0430\u044e\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0438\u0437 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0431\u044b\u043b \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d.<\/p>\n<h4>\u042d\u043a\u0441\u0442\u0440\u0435\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0437\u0430\u043b\u0430\u0437 \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440<\/h4>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0432\u0435\u0449\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b (\u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b\/\u0447\u0435\u043a\u0435\u0440\u044b\/etc.) \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a &#171;\u043f\u043b\u0430\u0433\u0438\u043d&#187; \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 AST (\u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430), \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/foonathan\/cppast\" rel=\"noopener noreferrer nofollow\">cppast<\/a>.<\/p>\n<p>AST \u044d\u0442\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043c\u0435\u0436\u0434\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0438 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043e\u043c. \u041a \u043d\u0435\u043c\u0443 \u043d\u0430\u0434\u043e \u043f\u0440\u0438\u0432\u044b\u043a\u043d\u0443\u0442\u044c, \u043d\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u0434\u0430 \u043d\u0430 C++. \u0415\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u0441\u043c\u043e\u0442\u0440\u0435\u043b \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 GCC \u0438\u043b\u0438 Clang, \u0442\u043e\u0442 \u0437\u043d\u0430\u0435\u0442, \u0447\u0442\u043e \u0441 \u043d\u0443\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u043c\u0430\u043b\u043e\u0440\u0435\u0430\u043b\u044c\u043d\u043e.<\/p>\n<h2>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u0432 C++<\/h2>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043c\u043d\u043e\u0433\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u043e\u0432, \u0433\u0434\u0435 \u0441 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432 <strong>run-time<\/strong>, \u0434\u0443\u0445 C++ \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0432 <strong>compile-time<\/strong>.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u044f\u0437\u044b\u043a \u0441\u0442\u0430\u0440\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 &#171;don\u2019t pay for what you don\u2019t use&#187;, \u0442\u043e ~95% \u0432\u0441\u0435\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u0430\u0440\u044f\u0435\u0442\u0441\u044f. \u0412 \u044f\u0437\u044b\u043a\u0435 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 \u0431\u0435\u0437 \u0440\u0430\u0437\u0434\u0443\u0432\u0430\u043d\u0438\u044f \u0431\u0438\u043d\u0430\u0440\u044f \u0447\u0435\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u043d\u0430\u0432\u0440\u043e\u0434\u0435 <a href=\"https:\/\/en.wikibooks.org\/wiki\/C%2B%2B_Programming\/RTTI\" rel=\"noopener noreferrer nofollow\">RTTI<\/a> (\u0441 \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043e\u0431\u044a\u0435\u043c\u043e\u043c).<\/p>\n<p>C++ \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0441\u0431\u043e\u0440\u043d\u0438\u043a \u0438\u0437 &#171;\u043f\u043e\u0434-\u044f\u0437\u044b\u043a\u043e\u0432&#187;, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 &#171;\u0443\u0440\u043e\u0432\u043d\u044f\u0445&#187;. \u0423\u0441\u043b\u043e\u0432\u043d\u043e\u0435 \u0434\u0435\u043b\u0435\u043d\u0438\u0435:<\/p>\n<ul>\n<li>\n<p><strong>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e C++<\/strong>: \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u0430\u043c\u044f\u0442\u044c\u044e, \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438, \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 (\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0441 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u041e\u0421), \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 <strong>run-time<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>\u0428\u0430\u0431\u043b\u043e\u043d\u044b<\/strong>: \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 (\u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f) \u0432 <strong>compile-time<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Constexpr-\u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f<\/strong>: \u044d\u0442\u043e &#171;\u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0435&#187; \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e &#171;\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e C++&#187;, \u043e\u0442 \u0433\u043e\u0434\u0430 \u0432 \u0433\u043e\u0434 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u043d\u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 <a href=\"https:\/\/habr.com\/ru\/post\/579490\/\" rel=\"noopener noreferrer nofollow\">\u043c\u043e\u0435\u0439 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>. \u0412\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <strong>compile-time<\/strong> \u043f\u0440\u044f\u043c\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440<\/strong>: \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438 (\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438) \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432. \u0421 C++ \u0438\u043c\u0435\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0441\u0432\u044f\u0437\u044c, \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f Rust\/Java\/C#\/etc. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 &#171;\u043f\u043e\u0434-\u044f\u0437\u044b\u043a\u043e\u0432&#187; \u043d\u0435 \u0442\u044c\u044e\u0440\u0438\u043d\u0433-\u043f\u043e\u043b\u043d\u044b\u0439. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 <strong>compile-time<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0432 \u0432\u0438\u0434\u0435 \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043d\u044b\u0445 \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432 \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043e \u0438\u0437-\u0437\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u0442\u044c\u044e\u0440\u0438\u043d\u0433-\u043f\u043e\u043b\u043d\u043e\u0442\u044b. \u041e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0438\u043b\u0438 constexpr-\u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0432\u0432\u0435\u0441\u0442\u0438 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0439 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0435, \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e\u0442 \u0432\u0432\u0435\u0441\u0442\u0438 \u0432 constexpr-\u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0435 (\u0442\u0430\u043a \u043a\u0430\u043a \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 constexpr \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u043b\u0438\u0441\u044c).<\/p>\n<p>\u042f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043e\u0431\u0435\u0438\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432, \u0438 \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e <strong>\u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/strong> \u043a\u043e\u0434 \u0441 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c.<\/p>\n<h2>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445<\/h2>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u0440\u043e \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445 &#8212; pdf-\u043a\u0430 <a href=\"https:\/\/cplusplus.github.io\/reflection-ts\/draft.pdf\" rel=\"noopener noreferrer nofollow\">Reflection TS<\/a>, \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0435\u0441\u0442\u044c \u043d\u0430 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/experimental\/reflect\" rel=\"noopener noreferrer nofollow\">cppreference.com<\/a>.<\/p>\n<p>\u0421\u0432\u043e\u0439 \u043a\u043e\u0434 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 <a href=\"https:\/\/godbolt.org\/\" rel=\"noopener noreferrer nofollow\">godbolt.org<\/a>, \u0432\u044b\u0431\u0440\u0430\u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 <code>x86-64 clang (reflection)<\/code>.<\/p>\n<p>\u0412\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>reflexpr(X)<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e &#171;\u0441\u043a\u043e\u0440\u043c\u0438\u0442\u044c&#187; \u0432\u043c\u0435\u0441\u0442\u043e <code>X<\/code> \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e: \u0442\u0438\u043f, \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0438\u043c\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430, \u0438 \u0442.\u0434.<\/p>\n<p>\u042d\u0442\u043e\u0442 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u0435\u0440\u043d\u0435\u0442 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 <em>meta-object type<\/em> (\u0434\u0430\u043b\u0435\u0435 &#8212; \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0438\u043f&#187;), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043b\u044f \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u043c incomplete \u043a\u043b\u0430\u0441\u0441\u043e\u043c. \u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430:<\/p>\n<pre><code class=\"cpp\">enum Color {     Red, Green, Blue };  using MetaT = reflexpr(Color);<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0443 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u043e\u0432 (\u0432 <code>Reflection TS<\/code> \u0435\u0441\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u043e\u0432).<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>MetaT<\/code> \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0443 <code>reflect::Enum<\/code>, \u0438 \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 <code>reflect::Variable<\/code> &#8212; <a href=\"https:\/\/godbolt.org\/z\/Tf63PKEhG\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0434<\/a> \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439.<\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e &#171;\u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0439&#187; \u043e\u0434\u043d\u0438\u0445 \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445. \u0421\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u0438\u043c \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0430\u043c \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0438\u043f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>Reflection TS<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u043c <code>reflect::Enum<\/code> \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0442\u0438\u043f\u0430\u043c:<\/p>\n<pre><code class=\"cpp\">template &lt;Enum T> struct get_enumerators;  \/\/ \u0438 \u0435\u0433\u043e short-hand template &lt;Enum T> using get_enumerators_t = typename get_enumerators&lt;T>::type;<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f <code>get_enumerators_t&lt;MetaT><\/code> \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u0421 \u0435\u0435 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0434\u0440\u0443\u0433\u043e\u0439 \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0438\u043f, \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0439 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0443 <code>reflect::ObjectSequence<\/code>.<\/p>\n<p>\u0412\u044b\u0432\u0435\u0434\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 <code>enum Color<\/code> \u0441\u043f\u0443\u0441\u0442\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">int main() {     constexpr std::string_view name = get_name_v&lt;get_element_t&lt;0, get_enumerators_t&lt;MetaT>>>;     std::cout &lt;&lt; \"The name of the first value is \\\"\" &lt;&lt; name &lt;&lt; \"\\\"\" &lt;&lt; std::endl; }<\/code><\/pre>\n<p><a href=\"https:\/\/godbolt.org\/z\/6Prs3fT1b\" rel=\"noopener noreferrer nofollow\">\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0434<\/a>.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043f\u0440\u0435\u0442\u0435\u043d\u0437\u0438\u044f \u043a \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u043c\u0443 \u043f\u043e\u0434\u0445\u043e\u0434\u0443 &#8212; \u043d\u0435\u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0441\u0442\u044c, \u043a\u0430\u043a \u043d\u0430\u0434\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434. \u041c\u044b \u0445\u043e\u0442\u0438\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0446\u0438\u043a\u043b \u043f\u043e <code>ObjectSequence<\/code>? \u041e\u0431\u044b\u0447\u043d\u044b\u043c for-\u043e\u043c \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f, \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u0437 \u043d\u0435\u0433\u043e, \u0438 \u043d\u0435\u043a\u0438\u0439 unpack_sequence:<\/p>\n<pre><code class=\"cpp\">template &lt;ObjectSequence T> struct get_size; template &lt;size_t I, ObjectSequence T> struct get_element; template &lt;template &lt;class...> class Tpl, ObjectSequence T>   struct unpack_sequence;<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443, \u043a\u0430\u043a \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e enum-\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043d\u0430\u0434\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u0436\u0443\u0442\u044c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e &#8212; <a href=\"https:\/\/gist.github.com\/Izaron\/290afdfc8af4ff81ceea11a10b2e57d4\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0434 \u0432 gist<\/a>.<\/p>\n<h2>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432 constexpr<\/h2>\n<p>\u042f\u0437\u044b\u043a \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0442 \u0436\u0438\u0432\u044b\u0435 \u043b\u044e\u0434\u0438, \u0443 \u043d\u0438\u0445 \u0442\u043e\u0436\u0435 \u0438\u0434\u0435\u0442 \u043a\u0440\u043e\u0432\u044c \u0438\u0437 \u0433\u043b\u0430\u0437 \u043f\u0440\u0438 \u0432\u0438\u0434\u0435 \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0439\u0447\u0430\u0441 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u0440\u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 &#8212; \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2021\/p2320r0.pdf\" rel=\"noopener noreferrer nofollow\">P2320<\/a>, \u0432\u0438\u0434\u0435\u043e-\u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 Andrew Sutton <a href=\"https:\/\/youtu.be\/60ECEc-URP8\" rel=\"noopener noreferrer nofollow\">\u043d\u0430 \u044e\u0442\u0443\u0431\u0435<\/a>, \u0438 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e <a href=\"https:\/\/github.com\/lock3\/meta\/wiki\/Reflection-Introductory-Tutorial\" rel=\"noopener noreferrer nofollow\">Wiki<\/a> \u0432 \u0433\u0438\u0442\u0445\u0430\u0431\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 <code>^X<\/code> \u043f\u0435\u0440\u0435\u0434 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e <code>X<\/code>. \u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 constexpr-<strong>\u043e\u0431\u044a\u0435\u043a\u0442<\/strong> \u0442\u0438\u043f\u0430 <code>std::experimental::meta::info<\/code>.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0432 compile-time) \u043c\u043e\u0436\u043d\u043e &#171;\u0432\u0435\u0440\u043d\u0443\u0442\u044c&#187; \u0435\u0433\u043e \u0432 &#171;\u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439&#187; \u043c\u0438\u0440 \u0447\u0435\u0440\u0435\u0437 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>[:X:]<\/code> (\u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f &#171;splice&#187;). \u0417\u0430\u043f\u0438\u0441\u044c <code>[:^X:]<\/code> \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u0430 <code>X<\/code>.<\/p>\n<p>Andrew Sutton \u0432 \u0432\u0438\u0434\u0435\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0438\u0433\u0440\u0443\u0448\u0435\u0447\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0442\u0438\u043f\u0430 <code>T****...*<\/code> (\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0432\u0451\u0437\u0434\u043e\u0447\u0435\u043a \u0440\u0430\u0432\u043d\u043e N). \u0412\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u044b:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T, int N> auto make_indirect_template() {     if constexpr (N == 0) {         return T{};     } else {         return make_indirect_template&lt;T*, N - 1>();     } }<\/code><\/pre>\n<p>\u0410 \u0432\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e:<\/p>\n<pre><code class=\"cpp\">consteval meta::info make_pointer(meta::info type, int n) {     for (int i = 0; i &lt; n; ++i) {         type = meta::add_pointer(type);     }     return type; }  template&lt;typename T, int N> auto make_indirect_reflective() {     return typename [:make_pointer(^T, N):]{}; }<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 consteval-\u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432 compile-time. \u0412\u0441\u0435 consteval-\u043c\u0435\u0442\u043e\u0434\u044b \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 &#171;\u0438\u0441\u043f\u0430\u0440\u044f\u044e\u0442\u0441\u044f&#187;, \u0442\u043e \u0435\u0441\u0442\u044c \u0438\u0445 \u043a\u043e\u0434 \u0432 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0438\u043c\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0445\u0441\u044f \u0442\u0438\u043f\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">int main() {     auto ptr1 = make_indirect_template&lt;int, 42>();     std::cout &lt;&lt; meta::name_of(meta::type_of(^ptr1)) &lt;&lt; std::endl;      auto ptr2 = make_indirect_reflective&lt;int, 42>();     std::cout &lt;&lt; meta::name_of(meta::type_of(^ptr2)) &lt;&lt; std::endl; }<\/code><\/pre>\n<p><a href=\"https:\/\/cppx.godbolt.org\/z\/v5b7zP36Y\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043d\u0430 godbolt<\/a> <\/p>\n<h3>\u0421\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 \u043e \u0437\u0430\u043f\u0438\u0441\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432<\/h3>\n<p>\u0417\u0430\u043f\u0438\u0441\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 <code>^X<\/code> \u0438 <code>[:X:]<\/code> \u043c\u043e\u0433\u0443\u0442 \u043d\u0435 \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0438 \u0432\u0438\u0434\u043e\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442. \u041d\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0443\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0437\u0430\u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p>\u0420\u0430\u043d\u0435\u0435 \u0432\u043c\u0435\u0441\u0442\u043e <code>^X<\/code> \u0431\u044b\u043b <code>reflexpr(X)<\/code>, \u0432\u043c\u0435\u0441\u0442\u043e <code>[:X:]<\/code> \u0431\u044b\u043b <code>unreflexpr(X)<\/code>.<\/p>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439&#187;, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/cplusplus\/papers\/issues\/1002\" rel=\"noopener noreferrer nofollow\">github-\u0442\u0438\u043a\u0435\u0442\u0435 \u043f\u0440\u043e P2320<\/a>.<\/p>\n<h3>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a<\/h3>\n<p>\u0421\u0432\u043e\u0439 \u043a\u043e\u0434 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430 <a href=\"https:\/\/cppx.godbolt.org\/\" rel=\"noopener noreferrer nofollow\">cppx.godbolt.com<\/a>, \u0432\u044b\u0431\u0440\u0430\u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 <code>p2320 trunk<\/code>.<\/p>\n<p>\u042d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u0438 \u0431\u044b\u0441\u0442\u0440\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044e \u0447\u0435\u0440\u0435\u0437 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b. \u0412 \u043b\u0443\u0447\u0448\u0438\u0445 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u044f\u0445 \u0444\u043e\u0440\u043a \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443 <a href=\"https:\/\/github.com\/lock3\/meta\/wiki\/Build-Instructions\" rel=\"noopener noreferrer nofollow\">\u043f\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0441\u043e\u0437\u0434\u0430\u043b docker-\u043e\u0431\u0440\u0430\u0437.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0431\u043e\u0440\u043a\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c docker-\u043e\u0431\u0440\u0430\u0437\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>docker-\u043e\u0431\u0440\u0430\u0437 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u043f\u043e \u044d\u0442\u043e\u043c\u0443 <a href=\"https:\/\/gist.github.com\/Izaron\/b9cffc1270ecd102cf47d36e2f9b88a5\" rel=\"noopener noreferrer nofollow\">Dockerfile<\/a>, \u0441\u043e\u0431\u0438\u0440\u0430\u043b \u0432\u0435\u0442\u043a\u0443 <a href=\"https:\/\/github.com\/lock3\/meta\/tree\/paper\/p2320\" rel=\"noopener noreferrer nofollow\">paper\/p2320<\/a>.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c:<\/p>\n<pre><code>docker pull sehnsucht88\/clang-p2320<\/code><\/pre>\n<p>\u041f\u0443\u0441\u0442\u044c \u0432\u0430\u0448 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a <code>code.cpp<\/code> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>\/home\/username\/cpp<\/code>, \u0442\u043e\u0433\u0434\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code>docker run --rm -v \/home\/username\/cpp:\/cpp sehnsucht88\/clang-p2320 -std=c++2a -freflection -stdlib=libc++ \/cpp\/code.cpp -o \/cpp\/bin<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>\/home\/username\/cpp<\/code> \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u044b\u0439 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a <code>bin<\/code><\/p>\n<p>\u041d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0444\u043e\u0440\u043a &#8212; <a href=\"https:\/\/github.com\/Izaron\/meta\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Izaron\/meta<\/a>.<\/p>\n<\/div>\n<\/details>\n<h2>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0432\u043d\u043e\u0435.<\/p>\n<h3>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 enum-\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438<\/h3>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 &#171;\u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445&#187;, \u0432 &#171;\u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u043d\u0430 constexpr&#187; \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0449\u0435. \u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430 (\u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b \u043a\u043e\u0434 \u0438\u0437 <a href=\"https:\/\/youtu.be\/60ECEc-URP8\" rel=\"noopener noreferrer nofollow\">\u0432\u0438\u0434\u0435\u043e Andrew Sutton<\/a>):<\/p>\n<pre><code class=\"cpp\">template&lt;typename T> requires std::is_enum_v&lt;T> constexpr std::string_view to_string(T value) {     template for (constexpr meta::info e : meta::members_of(^T)) {         if ([:e:] == value) {             return meta::name_of(e);         }     }     throw std::runtime_error(\"Unknown enum value\"); }<\/code><\/pre>\n<p><code>template for<\/code> &#8212; \u044d\u0442\u043e \u0444\u0438\u0447\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435 \u0443\u0441\u043f\u0435\u043b\u0430 \u0432\u043e\u0439\u0442\u0438 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 C++20. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d\u0430 \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442 range \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0430. \u041f\u0443\u0441\u0442\u044c \u0443 \u043d\u0430\u0441 \u0442\u0430\u043a\u043e\u0439 enum:<\/p>\n<pre><code class=\"cpp\">enum LightColor { Red, Green, Blue };<\/code><\/pre>\n<p>\u0422\u043e\u0433\u0434\u0430 \u043c\u0435\u0442\u043e\u0434 \u0440\u0430\u0441\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0432 \u0442\u0430\u043a\u043e\u0439 \u0432\u0438\u0434:<\/p>\n<pre><code class=\"cpp\">template&lt;> constexpr std::string_view to_string&lt;LightColor>(T value) {     { if (Red == value) return \"Red\"; }     { if (Green == value) return \"Green\"; }     { if (Blue == value) return \"Blue\"; }     throw std::runtime_error(\"Unknown enum value\"); }<\/code><\/pre>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u0432\u0435\u0440\u043d\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 enum-\u0430<\/p>\n<details class=\"spoiler\">\n<summary>\u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a from_string<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">template&lt;typename T> requires std::is_enum_v&lt;T> constexpr std::optional&lt;T> from_string(std::string_view value) {     template for (constexpr meta::info e : meta::members_of(^T)) {         if (meta::name_of(e) == value) {             return [:e:];         }     }     return {}; }<\/code><\/pre>\n<\/div>\n<\/details>\n<p><a href=\"https:\/\/cppx.godbolt.org\/z\/Yc8dhfGW7\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043d\u0430 godbolt<\/a><\/p>\n<h3>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0430 internal linkage<\/h3>\n<p>\u041c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0432\u0438\u0434\u0438\u043c\u044b\u0445 &#171;\u0441\u043d\u0430\u0440\u0443\u0436\u0438&#187; (\u0432\u043d\u0435 \u0435\u0434\u0438\u043d\u0438\u0446\u044b \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438) \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 <code>meta::is_externally_linked<\/code>.<\/p>\n<p>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043e\u0442\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 &#8212; \u0432 \u0444\u043e\u0440\u043a\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0432 compile-time:<\/p>\n<ul>\n<li>\n<p><code>__reflect_dump<\/code> &#8212; \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>meta::info<\/code>, \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b AST \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0435\u043c\u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p><code>__compiler_error<\/code> &#8212; \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443, \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><code>__concatenate<\/code> &#8212; \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0445 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432 \u0432 \u043e\u0434\u0438\u043d.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0435\u0440\u0432\u044b\u0435 \u0434\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 compile-time \u043a\u043e\u0434\u0430. \u0422\u0440\u0435\u0442\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u043d\u0443\u0436\u0435\u043d, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>std::string<\/code> \u0432 compile-time \u043f\u043e\u043a\u0430 \u0435\u0449\u0435 \u043d\u0435\u0442 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0435 (\u043d\u043e \u043a\u043e\u0433\u0434\u0430-\u0442\u043e \u0431\u0443\u0434\u0435\u0442).<\/p>\n<p>\u041f\u0440\u043e <code>meta::info<\/code> \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u0444\u0430\u043a\u0442 &#8212; \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cpp\">consteval void foo(meta::info r) { \/* ... *\/ }<\/code><\/pre>\n<p>\u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0434\u0443\u043c\u0430\u0435\u0442, \u0447\u0442\u043e <code>meta::info<\/code> \u043f\u0440\u043e\u0442\u0435\u043a\u0430\u0435\u0442 \u0432 run-time&#8230; \u0417\u0430\u0442\u043e \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cpp\">template&lt;meta::info R> consteval void foo() { \/* ... *\/ }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0440\u0435\u0448\u0438\u0442\u044c \u043d\u0430\u0448\u0443 \u0437\u0430\u0434\u0430\u0447\u0443. \u041c\u0435\u0442\u043e\u0434\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 namespace. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0432\u0441\u0435\u043c \u0447\u043b\u0435\u043d\u0430\u043c namespace, \u044f\u0432\u043b\u044f\u044e\u0449\u0438\u043c\u0438\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 namespace, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0445 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e.<\/p>\n<pre><code class=\"cpp\">template&lt;meta::info R> consteval void check_functions_linkage() {     static_assert(meta::is_namespace(R));      template for (constexpr meta::info e : meta::members_of(R)) {         if constexpr (meta::is_function(e)) {             __reflect_dump(e);             if constexpr (meta::is_externally_linked(e)) {                 constexpr auto error_msg =                     __concatenate(\"The method '\", meta::name_of(e), \"' is externally linked\");                 __compiler_error(error_msg);             }         }          if constexpr (meta::is_namespace(e)) {             check_functions_linkage&lt;e>();         }     } }<\/code><\/pre>\n<p>\u0417\u0430\u0432\u0435\u0434\u0435\u043c \u0438\u0433\u0440\u0443\u0448\u0435\u0447\u043d\u044b\u0439 namespace &#8212; \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0430\u0434\u0430\u0442\u044c \u0442\u0430\u043a, \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e:<\/p>\n<pre><code class=\"cpp\">namespace outer {     bool foo(int i) { return i == 13; }     std::string bar(std::string s) { return s + s; };      namespace inner {         double fizz() { return 3.14; }     } \/\/ namespace inner } \/\/ namespace outer  int main() {     check_functions_linkage&lt;^outer>();     std::cout &lt;&lt; \"compiled!\" &lt;&lt; std::endl; }<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b\u0430 \u043f\u0430\u0434\u0430\u0442\u044c, \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0438\u043c\u0435\u044e\u0449\u0438\u043c\u0438 internal linkage.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043f\u043e\u0441\u043e\u0431\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>static<\/code><\/p>\n<pre><code class=\"cpp\">namespace outer {     static bool foo(int i) { return i == 13; }     static std::string bar(std::string s) { return s + s; };      namespace inner {         static double fizz() { return 3.14; }     } \/\/ namespace inner } \/\/ namespace outer<\/code><\/pre>\n<p>\u0418\u043b\u0438 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0433\u043e namespace<\/p>\n<pre><code class=\"cpp\">namespace outer { namespace {     bool foo(int i) { return i == 13; }     std::string bar(std::string s) { return s + s; };      namespace inner {         double fizz() { return 3.14; }     } \/\/ namespace inner } \/\/ anonymous namespace } \/\/ namespace outer<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0432\u0441\u0451, \u0434\u043e \u0447\u0435\u0433\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0442\u044f\u043d\u0443\u0442\u044c\u0441\u044f &#8212; \u0435\u0441\u043b\u0438 \u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c\u0443 namespace (\u043e\u043d \u0436\u0435 <code>::<\/code>). \u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e namespace \u044d\u0442\u043e <code>^::<\/code>.<\/p>\n<p><a href=\"https:\/\/cppx.godbolt.org\/z\/nPYanasYP\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043d\u0430 godbolt<\/a><\/p>\n<h3>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0447\u0442\u043e \u0442\u0438\u043f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c<\/h3>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0442\u0438\u043f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u043c&#187;, \u0442\u043e \u0435\u0441\u0442\u044c \u0438\u043c\u0435\u0435\u0442 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d <em>\u0447\u0438\u0441\u0442\u043e \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439<\/em> \u043c\u0435\u0442\u043e\u0434, \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_abstract\" rel=\"noopener noreferrer nofollow\">std::is_abstract<\/a>.<\/p>\n<p>\u041f\u043e\u043d\u044f\u0442\u0438\u0435 &#171;\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441&#187; \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0435 \u043d\u0435 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043e, \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<ol>\n<li>\n<p>\u0412\u0441\u0435 user-defined \u043c\u0435\u0442\u043e\u0434\u044b (\u0442.\u0435. \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044e\u0437\u0435\u0440 \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0441\u0430\u043c, \u0430 \u043d\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c) <em>\u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435<\/em> \u0438 <em>\u0447\u0438\u0441\u0442\u043e \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435.<\/em><\/p>\n<\/li>\n<li>\n<p>\u0423 \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441\u0435 \u0435\u0441\u0442\u044c <em>\u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440<\/em>, \u044f\u0432\u043b\u044f\u044e\u0449\u0438\u0439\u0441\u044f <em>defaulted<\/em>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<pre><code class=\"cpp\">namespace traits {  template&lt;typename T> consteval bool is_interface_impl() {     constexpr meta::info refl = ^T;     if constexpr (meta::is_class(refl)) {         template for (constexpr meta::info e : meta::members_of(refl)) {             \/\/ interfaces SHALL NOT have data members             if constexpr (meta::is_data_member(e)) {                 return false;             }             \/\/ every user function in interfaces SHOULD BE public and pure virtual             if constexpr (meta::is_function(e) &amp;&amp; !meta::is_special_member_function(e)) {                 if constexpr (!meta::is_public(e) || !meta::is_pure_virtual(e)) {                     return false;                 }             }             \/\/ the destructor SHOULD BE virtual and defaulted             if constexpr (meta::is_function(e) &amp;&amp; meta::is_destructor(e)) {                 if constexpr (!meta::is_public(e) || !meta::is_defaulted(e) || !meta::is_virtual(e)) {                     return false;                 }             }         }         return true;     }     return false; }  template&lt;typename T> constexpr bool is_interface = is_interface_impl&lt;T>();  } \/\/ namespace traits<\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>\u0420\u0430\u0437\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/ IS NOT abstract, IS NOT interface class foo { public:     void foo_void(); private:     int _foo_int; }; static_assert(not std::is_abstract_v&lt;foo>); static_assert(not traits::is_interface&lt;foo>);  \/\/ IS abstract, IS NOT interface class bar { public:     virtual void bar_void() = 0;     std::string bar_string(); private:     int _foo_int; }; static_assert(    std::is_abstract_v&lt;bar>); static_assert(not traits::is_interface&lt;foo>);  \/\/ IS abstract, IS NOT interface class fizz { public:     virtual void fizz_void() = 0;     std::string fizz_string(); }; static_assert(    std::is_abstract_v&lt;fizz>); static_assert(not traits::is_interface&lt;fizz>);  \/\/ IS abstract, IS NOT interface class buzz { public:     virtual void buzz_void() = 0;     virtual std::string buzz_string() = 0; }; static_assert(    std::is_abstract_v&lt;buzz>); static_assert(not traits::is_interface&lt;buzz>);  \/\/ IS abstract, IS NOT interface class biba { public:     virtual ~biba() { \/* ... not defaulted dtor ... *\/ };     virtual void biba_void() = 0;     virtual std::string biba_string() = 0; }; static_assert(    std::is_abstract_v&lt;biba>); static_assert(not traits::is_interface&lt;biba>);  \/\/ IS abstract, IS interface class boba { public:     virtual ~boba() = default;     virtual void boba_void() = 0;     virtual std::string boba_string() = 0; }; static_assert(    std::is_abstract_v&lt;boba>); static_assert(    traits::is_interface&lt;boba>);<\/code><\/pre>\n<\/div>\n<\/details>\n<p><a href=\"https:\/\/cppx.godbolt.org\/z\/vWMxPx99z\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043d\u0430 godbolt<\/a><\/p>\n<h3>\u0421\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 JSON<\/h3>\n<p>\u0421\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432 JSON \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0439 FizzBuzz \u0434\u043b\u044f \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u0435\u0439 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438. \u041a\u0430\u0436\u0434\u044b\u0439 \u0443\u0432\u0430\u0436\u0430\u044e\u0449\u0438\u0439 \u0441\u0435\u0431\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u044d\u0442\u043e \u043d\u0430\u043f\u0438\u0448\u0435\u0442.<\/p>\n<p>\u0412 \u0441\u0432\u043e\u0435\u043c \u0432\u0438\u0434\u0435\u043e Andrew Sutton \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u0441 JSON, \u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u0430\u043a \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434. \u041c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0432\u043e\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435\u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f, \u0442\u043e \u0441 &#171;\u0433\u043e\u043b\u044b\u043c&#187; JSON \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e &#8212; \u0432\u0441\u0451 \u043d\u0435\u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u0438 \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043b\u0435\u0437\u0435\u0448\u044c \u0432 \u0441\u0432\u0430\u043b\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u043e\u043b\u044f. \u041c\u043e\u0436\u043d\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c JSON \u0432 \u0441\u0432\u043e\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u043d\u043e \u044d\u0442\u043e \u0432\u043b\u0435\u0447\u0435\u0442 \u043a\u0443\u0447\u0443 \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0430 &#8212; \u0447\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438.<\/p>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/JSON#Data_types\" rel=\"noopener noreferrer nofollow\">\u0411\u0430\u0437\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b<\/a> JSON \u044d\u0442\u043e <code>Number<\/code>, <code>String<\/code>, <code>Boolean<\/code>, <code>Array<\/code>, <code>Object<\/code>; \u043f\u0443\u0441\u0442\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#8212; <code>null<\/code>. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430.<\/p>\n<p><code>Number<\/code> \u044d\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f, \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0439 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_arithmetic\" rel=\"noopener noreferrer nofollow\">std::is_arithmetic<\/a>:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T> concept JsonNumber = std::is_arithmetic_v&lt;T>;<\/code><\/pre>\n<p><code>String<\/code> \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0439 \u0442\u0438\u043f, \u043f\u0440\u0438\u0447\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u043e\u043b\u0436\u0435\u043d <em>\u0432\u043b\u0430\u0434\u0435\u0442\u044c<\/em> \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u043d\u0430\u0442\u044c \u043e \u043d\u0435\u0439 (\u043a\u0430\u043a <code>std::string_view<\/code>). \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0433\u0434\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f &#8212; \u0442\u0430\u043c \u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u0435\u043d \u0432\u043b\u0430\u0434\u0435\u044e\u0449\u0438\u0439 \u0442\u0438\u043f. \u042d\u0442\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0442\u043e\u043b\u044c\u043a\u043e <code>std::string<\/code>:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T> concept JsonString = std::same_as&lt;std::string, T>;<\/code><\/pre>\n<p><code>Boolean<\/code> \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e <code>bool<\/code>:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T> concept JsonBoolean = std::same_as&lt;bool, T>;<\/code><\/pre>\n<p><code>Array<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u044d\u0442\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/SequenceContainer\" rel=\"noopener noreferrer nofollow\">SequenceContainer<\/a> &#8212; <code>std::array<\/code>\/<code>std::vector<\/code>\/<code>std::deque<\/code>\/<code>std::forward_list<\/code>\/<code>std::list<\/code>.<\/p>\n<p>\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0430 \u0434\u043b\u044f \u043d\u0438\u0445 \u043d\u0435\u0442 &#8212; \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0438\u043b\u0430\u043c\u0438 \u043f\u043e \u0432\u043e\u0434\u0435 \u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0432\u043e\u0439 \u043a\u043e\u043d\u0446\u0435\u043f\u0442 \u0441 \u043d\u0443\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0447\u0442\u043e \u0442\u0438\u043f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0441\u0442\u0430\u043d\u0446\u0438\u0430\u0446\u0438\u0435\u0439 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u043a\u043e\u043d\u0446\u0435\u043f\u0442 JsonArray<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0441\u043f\u0443\u0441\u0442\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0448\u0438\u0431\u043e\u043a \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438&#8230;<\/p>\n<pre><code class=\"cpp\">static constexpr meta::info vector_refl = ^std::vector; static constexpr meta::info array_refl = ^std::array; static constexpr meta::info deque_refl = ^std::deque; static constexpr meta::info list_refl = ^std::list; static constexpr meta::info forward_list_refl = ^std::forward_list;  template&lt;typename T> consteval bool is_json_array_impl() {     if constexpr (meta::is_specialization(^T)) {         constexpr auto tmpl = meta::template_of(^T);         constexpr bool result =             tmpl == vector_refl || tmpl == array_refl ||             tmpl == deque_refl || tmpl == list_refl ||             tmpl == forward_list_refl;         return result;     }     return false; }  template&lt;typename T> concept JsonArray = is_json_array_impl&lt;T>();<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043a\u0430\u043a <code>tmpl == ^std::vector<\/code> \u043a\u0440\u0430\u0448\u0438\u0442 clang, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a.<\/p>\n<\/div>\n<\/details>\n<p><code>Object<\/code> \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043b\u0430\u0441\u0441\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430. \u0412 \u043d\u0435\u043c, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c\/\u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0442\u0438\u043f &#8212; \u0441\u043a\u0430\u0436\u0435\u043c, \u0431\u0435\u0437 \u0447\u043b\u0435\u043d\u043e\u0432 \u0441\u043e \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438. \u041d\u043e \u043f\u043e\u043a\u0430 \u043e\u0431\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u0431\u0430\u0437\u043e\u0432\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c.<\/p>\n<pre><code class=\"cpp\">template&lt;typename T> concept JsonObject = std::is_class_v&lt;T>;<\/code><\/pre>\n<p>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>null<\/code> \u043c\u043e\u0436\u043d\u043e \u0432\u0432\u0435\u0441\u0442\u0438 \u0434\u043b\u044f <code>std::optional<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<details class=\"spoiler\">\n<summary>\u043a\u043e\u043d\u0446\u0435\u043f\u0442 JsonNullable<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">static constexpr meta::info optional_refl = ^std::optional;  template&lt;typename T> consteval bool is_json_nullable_impl() {     if constexpr (meta::is_specialization(^T)) {         return meta::template_of(^T) == optional_refl;     }     return false; }  template&lt;typename T> concept JsonNullable = is_json_nullable_impl&lt;T>();<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u043e\u043c\u0443 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0443 \u043e\u043d \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0430\u043c\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 \u0441\u0432\u043e\u0435\u043c \u0432\u0438\u0434\u0435\u043e Andrew Sutton \u0434\u0430\u0435\u0442 \u043c\u0435\u0433\u0430-\u0441\u043e\u0432\u0435\u0442 &#8212; \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u0434\u0438\u043d \u0442\u0438\u043f \u043c\u043e\u0436\u0435\u0442 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0430\u043c, \u0442\u043e \u043d\u0435 \u043d\u0430\u0434\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0432\u0440\u043e\u0434\u0435:<\/p>\n<pre><code class=\"cpp\">    template&lt;Concept1 T>     void write(T const&amp; t) { \/* ... *\/ }      template&lt;Concept2 T>     void write(T const&amp; t) { \/* ... *\/ }      template&lt;Concept3 T>     void write(T const&amp; t) { \/* ... *\/ }<\/code><\/pre>\n<p>\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u043d\u0430 \u043d\u0435\u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u0430 \u043c\u0435\u0442\u043e\u0434\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0434\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044e, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044f \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u044b \u043f\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"cpp\">    template&lt;typename T>     void write(T const&amp; t) {         if constexpr (Concept1&lt;T>) {             write_concept1(t);         } else if constexpr (Concept2&lt;T>) {             write_concept2(t);         } else if constexpr (Concept3&lt;T>) {             write_concept3(t);         }     }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441 json_writer, \u043f\u0443\u0441\u0442\u044c \u043e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u0443\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u0442\u0440\u0438\u043c\u0438\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a<\/p>\n<pre><code class=\"cpp\">template&lt;typename Out> class json_writer { public:     json_writer(Out&amp; out)         : _out{out}     {}          \/\/ ... \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434 ...  private:     Out&amp; _out; };<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 &#171;\u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u043e\u043c&#187; \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 JSON-\u0442\u0438\u043f\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">    template&lt;typename T>     void write(T const&amp; t) {         if constexpr (JsonNullable&lt;T>) {             write_nullable(t);         } else if constexpr (JsonNumber&lt;T>) {             write_number(t);         } else if constexpr (JsonString&lt;T>) {             write_string(t);         } else if constexpr (JsonBoolean&lt;T>) {             write_boolean(t);         } else if constexpr (JsonArray&lt;T>) {             write_array(t);         } else if constexpr (JsonObject&lt;T>) {             write_object(t);         }     }<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0438\u0437 <code>write<\/code>, \u043c\u043e\u0433\u0443\u0442 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 <code>write<\/code> \u0441\u043d\u043e\u0432\u0430. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u044c nullable-\u0442\u0438\u043f\u0430:<\/p>\n<pre><code class=\"cpp\">    template&lt;JsonNullable T>     void write_nullable(T const&amp; t) {         if (t.has_value()) {             write(*t);         } else {             _out &lt;&lt; \"null\";         }     }<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0438\u0441\u0438 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0433\u043e, \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e, \u0431\u0443\u043b\u0435\u0432\u043e\u0433\u043e \u0442\u0438\u043f\u043e\u0432 \u043d\u0435\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b:<\/p>\n<pre><code class=\"cpp\">    template&lt;JsonNumber T>     void write_number(const T t) {         _out &lt;&lt; t;     }      template&lt;JsonString T>     void write_string(T const&amp; t) {         _out &lt;&lt; '\"' &lt;&lt; t &lt;&lt; '\"';     }      template&lt;JsonBoolean T>     void write_boolean(const T t) {         if (t) {             _out &lt;&lt; \"true\";         } else {             _out &lt;&lt; \"false\";         }     }<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0438\u0441\u044c \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430 &#8212; \u043d\u0430\u0434\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043f\u044f\u0442\u044b\u0435, \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b:<\/p>\n<pre><code class=\"cpp\">    template&lt;JsonArray T>     void write_array(T const&amp; t) {         _out &lt;&lt; '[';         bool is_first_item = true;         for (const auto&amp; item : t) {             if (is_first_item) {                 is_first_item = false;             } else {                 _out &lt;&lt; ',';             }             write(item);         }         _out &lt;&lt; ']';     }<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0438\u0441\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 &#8212; \u0441\u0430\u043c\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u0430\u044f, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0447\u043b\u0435\u043d\u0430\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u043b\u0435\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e:<\/p>\n<pre><code class=\"cpp\">    template&lt;JsonObject T>     void write_object(T const&amp; t) {         _out &lt;&lt; '{';         bool is_first_member = true;          template for (constexpr meta::info e : meta::members_of(^T)) {             if constexpr (meta::is_data_member([:^e:])) {                 if (is_first_member) {                     is_first_member = false;                 } else {                     _out &lt;&lt; ',';                 }                  _out &lt;&lt; '\"' &lt;&lt; meta::name_of(e) &lt;&lt; '\"';                 _out &lt;&lt; ':';                 write(t.[:e:]);             }         }          _out &lt;&lt; '}';     }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u043f\u0443\u0441\u0442\u044c \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043d\u0438\u0433, \u043e\u0434\u0438\u043d \u0430\u0434\u0440\u0435\u0441, \u0438 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e &#171;\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435&#187;<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" height=\"360\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/461\/9f9\/c98\/4619f9c9841b65c0e2d8b78ed1225a58.png\" data-width=\"313\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"cpp\">namespace model {  struct book {     std::string name;     std::string author;     int year; };  struct latlon {     double lat;     double lon; };  struct library {     std::vector&lt;book> books;     std::optional&lt;std::string> description;     latlon address; };  } \/\/ namespace model<\/code><\/pre>\n<p>\u0417\u0430\u0434\u0430\u0434\u0438\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0430\u0434\u0440\u0435\u0441, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043d\u0438\u0433, \u0438 \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u0435\u0435 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 JSON:<\/p>\n<pre><code class=\"cpp\">int main() {     model::library l;     l.address = model::latlon{.lat = 51.507351, .lon = -0.127696};     l.books.push_back(model::book{         .name = \"The Picture of Dorian Gray\",         .author = \"Oscar Wilde\",         .year = 1890,     });     l.books.push_back(model::book{         .name = \"Fahrenheit 451\",         .author = \"Ray Bradbury\",         .year = 1953,     });     l.books.push_back(model::book{         .name = \"Roadside Picnic\",         .author = \"Arkady and Boris Strugatsky\",         .year = 1972,     });      json::json_writer{std::cout}.write(l);     std::cout &lt;&lt; std::endl; }<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u043d\u0435\u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 JSON:<\/p>\n<pre><code class=\"json\">{\"books\":[{\"name\":\"The Picture of Dorian Gray\",\"author\":\"Oscar Wilde\",\"year\":1890},{\"name\":\"Fahrenheit 451\",\"author\":\"Ray Bradbury\",\"year\":1953},{\"name\":\"Roadside Picnic\",\"author\":\"Arkady and Boris Strugatsky\",\"year\":1972}],\"description\":null,\"address\":{\"lat\":51.5074,\"lon\":-0.127696}}<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u0438\u0434 \u0442\u0430\u043a\u043e\u0439:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">{     \"books\": [         {             \"name\": \"The Picture of Dorian Gray\",             \"author\": \"Oscar Wilde\",             \"year\": 1890         },         {             \"name\": \"Fahrenheit 451\",             \"author\": \"Ray Bradbury\",             \"year\": 1953         },         {             \"name\": \"Roadside Picnic\",             \"author\": \"Arkady and Boris Strugatsky\",             \"year\": 1972         }     ],     \"description\": null,     \"address\": {         \"lat\": 51.5074,         \"lon\": -0.127696     } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p><a href=\"https:\/\/cppx.godbolt.org\/z\/hraGcG4qb\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043d\u0430 godbolt<\/a><\/p>\n<p>\u0415\u0441\u043b\u0438 \u0431\u044b \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e\/\u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u044f \u0431\u044b \u043f\u043e\u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u043b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c &#171;\u043f\u0440\u043e\u043a\u043b\u0430\u0434\u043a\u0443&#187; \u0432 \u0432\u0438\u0434\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 json-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <a href=\"https:\/\/github.com\/nlohmann\/json\" rel=\"noopener noreferrer nofollow\">nlohmann\/json<\/a>.<\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u0431\u044b \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 &#171;\u043d\u0430\u0448\u0435\u0439&#187; \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0437 json-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u0430 \u044d\u0442\u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0443\u0436\u0435 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f \u0431\u044b \u0432 \u0441\u0442\u0440\u043e\u043a\u0443. \u041f\u0440\u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442 &#8212; \u0441\u0442\u0440\u043e\u043a\u0430 \u0432 json-\u043e\u0431\u044a\u0435\u043a\u0442, json-\u043e\u0431\u044a\u0435\u043a\u0442 \u0432 &#171;\u043d\u0430\u0448&#187; \u043e\u0431\u044a\u0435\u043a\u0442.<\/p>\n<p>\u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434 &#8212; \u0441 &#171;\u043f\u0440\u043e\u043a\u043b\u0430\u0434\u043a\u043e\u0439&#187; \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u0440\u043e\u0449\u0435 \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u0435\u0435, \u0447\u0435\u043c \u0441\u0430\u043c\u043e\u043c\u0443 \u0447\u0442\u043e-\u0442\u043e \u043f\u0430\u0440\u0441\u0438\u0442\u044c.<\/p>\n<p>\u0422\u0430\u043a\u043e\u0439 \u0436\u0435 \u043f\u043e\u0434\u0445\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043b\u044f XML, <abbr title=\"Object-Relational Mapping\">ORM<\/abbr> \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u043f\u0440\u043e\u0447\u0435\u0433\u043e.<\/p>\n<h3>\u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0434\u0432\u0443\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/h3>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c <code>model::book<\/code> \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430. \u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0434\u0432\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438<\/p>\n<pre><code class=\"cpp\">    model::book a, b;     std::cout &lt;&lt; (a == b) &lt;&lt; std::endl; \/\/ \u0442\u0443\u0442 \u043e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438<\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f:<\/p>\n<ol>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c, \u0442\u043e \u0435\u0441\u0442\u044c \u0432\u044b\u0437\u043e\u0432 a == b \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f &#8212; \u0432\u044b\u0437\u043e\u0432 \u044d\u0442\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442 &#8212; \u0438\u0442\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 (\u043a\u0430\u043a std::vector), \u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442, \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0430\u0447\u0435 \u043f\u0440\u043e\u0438\u0442\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043f\u043e \u0447\u043b\u0435\u043d\u0430\u043c \u0442\u0438\u043f\u0430 \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u043b\u0435\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0438 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u044b \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043d\u0435 \u043d\u0430\u0448\u0435\u043b&#8230;<\/p>\n<pre><code class=\"cpp\">namespace bicycle {  template &lt;class T> constexpr bool equality_comparable = requires(const T&amp; a, const T&amp; b) {     std::is_convertible_v&lt;decltype(a == b), bool>; };  template &lt;class T> constexpr bool iterable = requires(const T&amp; t, size_t i) {     t[i];     std::begin(t);     std::end(t);     std::size(t); };  } \/\/ namespace bicycle<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0448 \u043c\u0435\u0442\u043e\u0434, \u043a\u0430\u043a \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u0438 &#8212; \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u043e \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u0443\u043d\u043a\u0442? \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043d\u0435\u0442 &#8212; \u043f\u0435\u0440\u0432\u044b\u0439 \u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0443\u043d\u043a\u0442 \u043d\u0430\u0434\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043c\u0435\u0441\u0442\u0430\u043c\u0438<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u043d\u0446\u0435\u043f\u0442\u044b \u0438\u043d\u043e\u0433\u0434\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0435 \u0442\u0430\u043a, \u043a\u0430\u043a \u043e\u0436\u0438\u0434\u0430\u043b\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u043d\u0446\u0435\u043f\u0442, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0443:<\/p>\n<pre><code class=\"cpp\">static_assert(    bicycle::equality_comparable&lt;int>); static_assert(    bicycle::equality_comparable&lt;std::string>); static_assert(    bicycle::equality_comparable&lt;std::optional&lt;std::string>>); static_assert(    bicycle::equality_comparable&lt;std::vector&lt;model::book>>); \/\/ &lt;&lt;&lt; :( static_assert(not bicycle::equality_comparable&lt;model::book>); static_assert(not bicycle::equality_comparable&lt;model::library>);<\/code><\/pre>\n<p>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0434\u0432\u0443\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 <code>model::book<\/code> \u043d\u0435 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0442\u0438\u043f\u0430 <code>std::vector&lt;model::book><\/code>. \u041d\u043e \u043a\u043e\u043d\u0446\u0435\u043f\u0442 \u0440\u0435\u0437\u043e\u043b\u044c\u0432\u0438\u0442\u0441\u044f \u0432 <code>true<\/code>!<\/p>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u0446\u0435\u043f\u0442 \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443 \u043c\u0435\u0442\u043e\u0434\u0430, \u0430 \u043d\u0435 \u043d\u0430 \u0432\u0435\u0441\u044c \u043c\u0435\u0442\u043e\u0434. \u041e\u043d \u0432\u0438\u0434\u0438\u0442, \u0447\u0442\u043e \u0443 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f <em>\u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d<\/em>:<\/p>\n<pre><code class=\"cpp\">template&lt; class T, class Alloc > bool operator==( const std::vector&lt;T,Alloc>&amp; lhs,                  const std::vector&lt;T,Alloc>&amp; rhs );<\/code><\/pre>\n<p>\u0410 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 \u043e\u043d \u043d\u0435 \u043b\u0435\u0437\u0435\u0442, \u043a \u0442\u043e\u043c\u0443 \u0436\u0435 \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e &#8212; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u043e\u043c translation unit. \u0422\u043e, \u0447\u0442\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 \u043a\u043e\u0434 \u043d\u0435 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0434\u043b\u044f \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0430 \u044d\u0442\u043e &#171;\u0443\u0436\u0435 \u043d\u0435 \u0435\u0433\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b&#187;.<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0448 \u043c\u0435\u0442\u043e\u0434:<\/p>\n<pre><code class=\"cpp\">namespace equal_util {  template&lt;typename T> bool equal(const T&amp; a, const T&amp; b) {     if constexpr (bicycle::iterable&lt;T>) {         if (a.size() != b.size()) {             return false;         }         for (size_t i = 0; i &lt; a.size(); ++i) {             if (!equal(a[i], b[i]))                 return false;         }         return true;     } else if constexpr (bicycle::equality_comparable&lt;T>) {         return a == b;     } else {         template for (constexpr meta::info e : meta::members_of(^T)) {             if constexpr (meta::is_data_member([:^e:])) {                 if (!equal(a.[:e:], b.[:e:])) {                     return false;                 }             }         }         return true;     } }  } \/\/ namespace equal_util<\/code><\/pre>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0441\u0442\u043e\u0438\u043b\u043e \u0431\u044b \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432 float \u0438 double \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0438\u0445 \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u0441 \u044d\u043f\u0441\u0438\u043b\u043e\u043d\u043e\u043c&#8230; \u041d\u043e \u043f\u043e\u043a\u0430 \u043e\u0431\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u0431\u0435\u0437 \u044d\u0442\u0438\u0445 \u043f\u043e\u0434\u0430\u0440\u043e\u0447\u043a\u043e\u0432.<\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043c\u0435\u0442\u043e\u0434 &#8212; \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437 \u0432\u044b\u0432\u0435\u0434\u0435\u0442\u0441\u044f <code>true<\/code>, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0437 <code>false<\/code>, \u0443\u0441\u043f\u0435\u0445!<\/p>\n<pre><code class=\"cpp\">int main() {     model::library a, b;      a.address = model::latlon{.lat = 51.507351, .lon = -0.127696};     b.address = a.address;      a.books.push_back(model::book{         .name = \"The Picture of Dorian Gray\",         .author = \"Oscar Wilde\",         .year = 1890,     });     b.books = a.books;      std::cout &lt;&lt; std::boolalpha;     std::cout &lt;&lt; equal_util::equal(a, b) &lt;&lt; std::endl;     b.books.clear();     std::cout &lt;&lt; equal_util::equal(a, b) &lt;&lt; std::endl; }<\/code><\/pre>\n<p><a href=\"https:\/\/cppx.godbolt.org\/z\/evYG8PfPM\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043d\u0430 godbolt<\/a><\/p>\n<h3>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 Dependency Injection<\/h3>\n<p>\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0434\u043b\u044f Dependency Injection!<\/p>\n<p>\u042d\u0442\u043e\u0442 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0445\u0430\u0440\u0434\u043a\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 Spring &#8212; \u0441\u0430\u043c\u043e\u043c \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u043c Java-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435.<\/p>\n<p>\u0412 \u043c\u043e\u0434\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u044b\u0447\u043d\u043e \u043e\u0434\u043d\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u0414\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c &#171;\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442&#187; \u0432\u043c\u0435\u0441\u0442\u043e &#171;\u043e\u0431\u044a\u0435\u043a\u0442&#187;.<\/p>\n<p>\u0421\u043c\u044b\u0441\u043b \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u044d\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0431\u044b <em>\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a<\/em>. \u0418 \u043f\u043e\u0442\u043e\u043c \u0434\u0430\u0432\u0430\u043b \u0431\u044b \u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 (\u0432\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u0440\u0430\u0437\u0443) \u043b\u0438\u0431\u043e \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0442\u0442\u0435\u0440-\u043c\u0435\u0442\u043e\u0434\u044b (\u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0441\u0435\u0442\u0442\u0435\u0440-\u043c\u0435\u0442\u043e\u0434\u0443 \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442).<\/p>\n<p>\u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0412 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0434\u043b\u0438\u043d\u0430 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043c\u043e\u0437\u0433\u0430.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0430-\u043b\u044f &#171;URL Shortener&#187;, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u043b\u0438\u043d\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435 (\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442). \u0423 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442, \u043e\u0447\u0435\u043d\u044c \u0443\u0441\u043b\u043e\u0432\u043d\u043e, \u0447\u0435\u0442\u044b\u0440\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 (\u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u043e\u0431\u043e\u043b\u044c\u0448\u0435):<\/p>\n<ol>\n<li>\n<p><strong>s3_storage<\/strong> &#8212; \u0441\u0435\u0440\u0432\u0438\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043c\u0435\u0435\u0442 \u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0438\u0437 s3-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0435\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>database<\/strong> &#8212; \u0441\u0435\u0440\u0432\u0438\u0441-&#171;\u043f\u0440\u043e\u043a\u043b\u0430\u0434\u043a\u0430&#187; \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p><strong>link_shortener<\/strong> &#8212; \u0441\u0435\u0440\u0432\u0438\u0441, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0434\u043b\u0438\u043d\u043d\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u0440\u043e\u0442\u043a\u0443\u044e (\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442). <em>\u0417\u0430\u0432\u0438\u0441\u0438\u0442<\/em> \u043e\u0442 <strong>database<\/strong>, \u0433\u0434\u0435 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u0441\u044b\u043b\u043a\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>http_server<\/strong> &#8212; \u0441\u0435\u0440\u0432\u0438\u0441, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e http. <em>\u0417\u0430\u0432\u0438\u0441\u0438\u0442<\/em> \u043e\u0442 <strong>s3_storage<\/strong> (\u043f\u043e\u043a\u0430\u0437 \u043b\u043e\u0433\u043e \u043d\u0430 \u0441\u0430\u0439\u0442\u0435), <strong>link_shortener<\/strong> (\u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0434\u043b\u044f \u0447\u0435\u0433\u043e), <strong>database<\/strong> (\u043a\u0443\u0434\u0430 \u043f\u0438\u0448\u0435\u0442 \u0432\u0441\u044f\u043a\u0443\u044e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0440\u043e \u043f\u043e\u0441\u0435\u0442\u0438\u0442\u0435\u043b\u044f \u0441\u0430\u0439\u0442\u0430).<\/p>\n<\/li>\n<\/ol>\n<figure class=\"\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" alt=\"\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435\" title=\"\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435\" height=\"297\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d44\/622\/ce8\/d44622ce847d7d130921a0be7a0bd250.png\" data-width=\"517\"\/><figcaption>\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435<\/figcaption><\/figure>\n<p>\u041e\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 \u043a\u043e\u0434\u0435:<\/p>\n<pre><code class=\"cpp\">namespace component {  class database { public:     void post_construct() {         \/* \u0442\u0443\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0411\u0414 *\/     }      \/* \u0442\u0443\u0442 \u043d\u0435\u043a\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043e\u0431 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u0445 \u0432 \u0411\u0414 *\/ };  class link_shortener { public:     void set_component(std::shared_ptr&lt;database> component) {         _database = std::move(component);     }      \/* \u0442\u0443\u0442 \u043d\u0435\u043a\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b link_shortener. *\/      \/* \u043c\u0435\u0442\u043e\u0434 post_construct() \u043d\u0435 \u043d\u0443\u0436\u0435\u043d *\/  private:     std::shared_ptr&lt;database> _database; };  class s3_storage { public:     \/* \u0442\u0443\u0442 \u043d\u0435\u043a\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b s3_storage. *\/      \/* \u043c\u0435\u0442\u043e\u0434 post_construct() \u043d\u0435 \u043d\u0443\u0436\u0435\u043d *\/ };  class http_server { public:     void set_component(std::shared_ptr&lt;s3_storage> component) {         _s3_storage = std::move(component);     }      void set_component(std::shared_ptr&lt;link_shortener> component) {         _link_shortener = std::move(component);     }      void set_component(std::shared_ptr&lt;database> component) {         _database = std::move(component);     }      void post_construct() {         \/* \u0442\u0443\u0442 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c http-\u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0436\u0434\u0451\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u044b *\/     }  private:     std::shared_ptr&lt;s3_storage> _s3_storage;     std::shared_ptr&lt;link_shortener> _link_shortener;     std::shared_ptr&lt;database> _database; };  } \/\/ namespace component<\/code><\/pre>\n<p>\u0427\u0442\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a:<\/p>\n<ol>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0447\u0435\u0440\u0435\u0437 <code>std::make_shared<\/code>, \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u0432\u0430\u0442\u044c <code>set_component<\/code> \u0441 \u0433\u043e\u0442\u043e\u0432\u044b\u043c\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 <code>set_component<\/code> \u0432\u044b\u0437\u0432\u0430\u043d\u044b, \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>post_construct<\/code>, \u0435\u0441\u043b\u0438 \u043e\u043d \u0435\u0441\u0442\u044c \u0432 \u043a\u043b\u0430\u0441\u0441\u0435. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0443 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043f\u043e\u0442\u043e\u043c \u0443 \u0437\u0430\u0432\u0438\u0441\u044f\u0449\u0438\u0445.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0433\u0434\u0430 &#171;\u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442&#187; (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>http_server<\/code>) \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 <code>post_construct<\/code>, \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0431\u044b\u043b\u0438 &#171;\u0436\u0438\u0432\u044b&#187;.<\/p>\n<\/li>\n<\/ol>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u043a\u043b\u0430\u0441\u0441\u0430:<\/p>\n<pre><code class=\"cpp\">namespace dependency_injection {  static constexpr meta::info shared_ptr_refl = ^std::shared_ptr;  class components_builder { public:     template&lt;typename Component>     std::shared_ptr&lt;Component> build() &amp;&amp; {         return build_component_impl&lt;Component>();     }  private:     using ready_components_container = std::unordered_map&lt;std::string_view, std::any>;     static constexpr std::string_view COMPONENT_INJECTION_FUNCTION_NAME = \"set_component\";     static constexpr std::string_view COMPONENT_POST_CONSTRUCT_FUNCTION_NAME = \"post_construct\";  private:     \/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b...    private:     ready_components_container _ready_components; };  } \/\/ namespace dependency_injection<\/code><\/pre>\n<p>\u0413\u043e\u0442\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0445\u0435\u0448\u043c\u0430\u043f\u0435. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0445\u0435\u0448\u043c\u0430\u043f\u044b \u0438\u043c\u0435\u044e\u0442 \u0442\u0438\u043f <code>std::any<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u043e\u0431\u0449\u0435\u0433\u043e \u0442\u0438\u043f\u0430.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434-&#171;\u043f\u0440\u043e\u043a\u043b\u0430\u0434\u043a\u0443&#187;, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0449\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432 \u0445\u0435\u0448\u043c\u0430\u043f\u0435, \u0430 \u0435\u0441\u043b\u0438 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u0442, \u0442\u043e \u0441\u0442\u0440\u043e\u0438\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442:<\/p>\n<pre><code class=\"cpp\">    \/\/ don't build component again if already has one built     template&lt;typename Component>     std::shared_ptr&lt;Component> build_or_get_component() {         std::shared_ptr&lt;Component> component;          constexpr std::string_view comp_name = meta::name_of(meta::entity_of(^Component));         if (auto _ready_iter = _ready_components.find(comp_name); _ready_iter != _ready_components.end()) {             component = std::any_cast&lt;decltype(component)>(_ready_iter->second);         } else {             component = build_component_impl&lt;Component>();             _ready_components[comp_name] = component;         }          return component;     }<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u0447\u0435\u0440\u0435\u0437 <code>std::make_shared<\/code>, \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e <code>set_component<\/code>, \u043f\u043e\u0442\u043e\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>post_construct<\/code> \u043f\u0440\u0438 \u0435\u0433\u043e \u043d\u0430\u043b\u0438\u0447\u0438\u0438.<\/p>\n<pre><code class=\"cpp\">    template&lt;typename Component>     std::shared_ptr&lt;Component> build_component_impl() {         auto component = std::make_shared&lt;Component>();         build_dependent_components(*component);         try_call_post_construct(*component);         return component;     }<\/code><\/pre>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0438\u043c\u0435\u0435\u043c \u043b\u0438 \u043c\u044b \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0431\u043e\u0439 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u043c\u0435\u0442\u043e\u0434\u0430 \u0441 \u043d\u0443\u0436\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c:<\/p>\n<pre><code class=\"cpp\">    template&lt;meta::info R>     static constexpr bool is_callable_function(std::string_view expected_function_name) {         \/\/ drop special functions and non-public functions         if constexpr (meta::is_function(R) &amp;&amp; meta::is_public(R) &amp;&amp; !meta::is_special_member_function(R)) {             constexpr std::string_view function_name = meta::name_of(R);             return function_name == expected_function_name;         }         return false;     }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b:<\/p>\n<ol>\n<li>\n<p>\u0418\u0449\u0435\u043c \u0432\u0441\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>set_component<\/code>. \u041f\u0443\u0441\u0442\u044c \u043c\u044b \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043e\u0434\u0438\u043d \u0442\u0430\u043a\u043e\u0439 \u043c\u0435\u0442\u043e\u0434.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440.<\/p>\n<\/li>\n<li>\n<p>\u0422\u0438\u043f \u044d\u0442\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 <code>std::shared_ptr<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u044b\u043b \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u0448\u0430\u0431\u043b\u043e\u043d &#8212; \u044d\u0442\u043e \u043a\u043b\u0430\u0441\u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c (\u0438\u043b\u0438 \u0432\u0437\u044f\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c).<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>set_component<\/code> \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c \u0438\u0437 \u043f. 4.<\/p>\n<\/li>\n<\/ol>\n<p>\u0421 \u044d\u0442\u0438\u043c \u043f\u043b\u0430\u043d\u043e\u043c \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <code>build_dependent_components<\/code>:<\/p>\n<pre><code class=\"cpp\">    template&lt;typename Component>     void build_dependent_components(Component&amp; component) {         template for (constexpr meta::info e : meta::members_of(^Component)) {             \/\/ iterate through functions             if constexpr (is_callable_function&lt;e>(COMPONENT_INJECTION_FUNCTION_NAME)) {                 \/\/ the function should have exactly one parameter                 constexpr auto param_range = meta::parameters_of(e);                 static_assert(size(param_range) == 1, \"Please pass only one parameter\");                 constexpr meta::info param = *param_range.begin();                  \/\/ the type of the parameter should be std::shared_ptr&lt;U>                 constexpr meta::info param_type = meta::type_of(param);                 static_assert(meta::is_specialization(param_type), \"Please pass std::shared_ptr&lt;component>\");                 static_assert(meta::template_of(param_type) == shared_ptr_refl, \"Please pass std::shared_ptr&lt;component>\");                  \/\/ obtain dependent component type                 using SharedPtrType = typename [:param_type:];                 using DependentComponentType = typename SharedPtrType::element_type;                  \/\/ build the dependent component (if not built yet) and give it to the original component                 auto dependent_component = build_or_get_component&lt;DependentComponentType>();                 component.[:e:](dependent_component);             }         }     }<\/code><\/pre>\n<p>\u0412\u044b\u0437\u043e\u0432 <code>post_construct<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u043e\u0449\u0435:<\/p>\n<pre><code class=\"cpp\">    template&lt;typename Component>     void try_call_post_construct(Component&amp; component) {         template for (constexpr meta::info e : meta::members_of(^Component)) {             if constexpr (is_callable_function&lt;e>(COMPONENT_POST_CONSTRUCT_FUNCTION_NAME)) {                 constexpr auto param_range = meta::parameters_of(e);                 static_assert(size(param_range) == 0, \"Please don't pass parameters in \\\"post_construct\\\"\");                 component.[:e:]();             }         }     }<\/code><\/pre>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c &#171;\u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442&#187; \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441:<\/p>\n<pre><code class=\"cpp\">int main() {     dependency_injection::components_builder().build&lt;component::http_server>(); }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043b\u043e\u0433 \u0438\u043c\u0435\u043d\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435, \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435, <code>set_component<\/code> \u0438 <code>post_construct<\/code>, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a:<\/p>\n<pre><code>call \"http_server::http_server()\" call \"s3_storage::s3_storage()\" call \"s3_storage::post_construct()\" &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; THE COMPONENT IS READY call \"http_server::set_component(std::shared_ptr&lt;s3_storage>)\" call \"link_shortener::link_shortener()\" call \"database::database()\" call \"database::post_construct()\" &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; THE COMPONENT IS READY call \"link_shortener::set_component(std::shared_ptr&lt;database>)\" call \"link_shortener::post_construct()\" &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; THE COMPONENT IS READY call \"http_server::set_component(std::shared_ptr&lt;link_shortener>)\" call \"http_server::set_component(std::shared_ptr&lt;database>)\" call \"http_server::post_construct()\" &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; THE COMPONENT IS READY call \"http_server::~http_server()\" call \"link_shortener::~link_shortener()\" call \"database::~database()\" call \"s3_storage::~s3_storage()\"<\/code><\/pre>\n<p>\u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0432\u0441\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e!<\/p>\n<p>\u0418\u0437 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c:<\/p>\n<ol>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u0446\u0438\u043a\u043b\u044b \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 &#8212; \u0438\u0445 \u0431\u044b\u0442\u044c \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e. \u041a\u0430\u0436\u0435\u0442\u0441\u044f, \u0446\u0438\u043a\u043b\u044b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0432 compile-time.<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u0430 \u043d\u0435 \u043e\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, &#171;\u043a\u0430\u043a \u0432 \u043b\u0443\u0447\u0448\u0438\u0445 \u0434\u043e\u043c\u0430\u0445 \u041f\u0430\u0440\u0438\u0436\u0443&#187;.<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u0430 \u043d\u0435 \u043e\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 <code>s3_storage<\/code> &#8212; \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043f\u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b <code>s3_storage<\/code> \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u0441\u044f \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>image_storage<\/code>, \u0438 \u0432 <code>http_server<\/code> \u0431\u044b\u043b \u0431\u044b \u043c\u0435\u0442\u043e\u0434 <code>set_component(std::shared_ptr&lt;image_storage>)<\/code>.<\/p>\n<p>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u043c\u043e\u0433\u043b\u0430 \u0431\u044b \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0432\u0435\u0441\u044c namespace, \u043d\u0430\u0439\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0433\u043e.<\/p>\n<\/div>\n<\/details>\n<h3>\u0414\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/h3>\n<p>\u041a\u0440\u043e\u043c\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0432\u044b\u0448\u0435, \u044f \u0441\u0434\u0435\u043b\u0430\u043b <a href=\"https:\/\/cppx.godbolt.org\/z\/3dj4d8WrW\" rel=\"noopener noreferrer nofollow\">hasattr.cpp<\/a> &#8212; \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432 <code>hasattr<\/code> \u0438 <code>getattr<\/code> \u0438\u0437 \u044f\u0437\u044b\u043a\u0430 Python, \u0430 \u0442\u0430\u043a\u0436\u0435 <a href=\"https:\/\/cppx.godbolt.org\/z\/cYerE1Ws9\" rel=\"noopener noreferrer nofollow\">opts.cpp<\/a> &#8212; \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<p>\u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u0438\u0445 \u044f \u043d\u0435 \u0441\u0442\u0430\u043b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u043e\u0432\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0442\u0430\u043c \u043d\u0435\u0442.<\/p>\n<p><strong>\u0412\u0441\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043d\u0430 github<\/strong> &#8212; <a href=\"https:\/\/github.com\/Izaron\/CxxReflectionSandbox\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0430<\/a>.<\/p>\n<h2>\u0427\u0442\u043e \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u0442\u044c \u043e\u0442 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c?<\/h2>\n<p>\u0427\u0430\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u043e\u0432 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f enum) \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u044b.<\/p>\n<p>\u0425\u043e\u0447\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0443\u043c\u0435\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/attributes\" rel=\"noopener noreferrer nofollow\">\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c\u0438<\/a>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u043b\u0430\u0441\u0442 \u043a\u0440\u0443\u0442\u044b\u0445 \u044e\u0437\u043a\u0435\u0439\u0441\u043e\u0432.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432\u043e\u0439\u0434\u0435\u0442 \u0432 C++ &#8212; \u043f\u043e\u043a\u0430 \u0442\u043e\u0447\u043d\u043e \u043d\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u043d\u043e \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0443\u0441\u043f\u0435\u044e\u0442 \u043a \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443 C++26.<\/p>\n<\/div>\n<\/div>\n<p> <!----> <!----><br \/> \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:\/\/habr.com\/ru\/post\/598981\/\"> https:\/\/habr.com\/ru\/post\/598981\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\" class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f &#171;\u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f&#187; \u0438\u0437 \u0412\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438:<\/p>\n<blockquote>\n<p>In computer science, <strong>reflective programming<\/strong> or <strong>reflection<\/strong> is the ability of a process to examine, introspect, and modify its own structure and behavior.<\/p>\n<\/blockquote>\n<p>\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0433\u043e\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0432\u0432\u043e\u0434\u0430 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 C++.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u043d\u0430 C++ \u0441 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0435\u0439 \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447, <strong>\u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c<\/strong> \u0435\u0433\u043e \u043d\u0430 \u0444\u043e\u0440\u043a\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0441 \u0440\u0430\u0431\u043e\u0447\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438.<\/p>\n<h2>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445<\/h2>\n<p>\u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445, \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0445\u0441\u044f \u0434\u043b\u044f \u0431\u044d\u043a\u0435\u043d\u0434\u0430, \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u043e\u0447\u0435\u043d\u044c \u043c\u043e\u0449\u043d\u0430\u044f. \u041f\u0430\u0440\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432:<\/p>\n<p>\u0412 \u044f\u0437\u044b\u043a\u0435 <strong>Python<\/strong> \u0432 run-time \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430; \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430; \u0432\u0441\u0435 \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u044b; \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432 \u043a\u043b\u0430\u0441\u0441; \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443, \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u043a\u043b\u0430\u0441\u0441 \u044d\u0442\u043e dict (\u0441 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0441\u0430\u0445\u0430\u0440\u043e\u043c), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u0443\u0433\u043e\u0434\u043d\u043e.<\/p>\n<p>\u0412 \u044f\u0437\u044b\u043a\u0435 <strong>Java<\/strong> \u0432 run-time \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430; \u0435\u0433\u043e \u043f\u043e\u043b\u044f, \u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b, \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b, \u0441\u0443\u043f\u0435\u0440\u043a\u043b\u0430\u0441\u0441\u044b; \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f \u043f\u043e \u0435\u0433\u043e \u0438\u043c\u0435\u043d\u0438; \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u043e \u0438\u043c\u0435\u043d\u0438; \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043a\u043b\u0430\u0441\u0441\u0430\u0445 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 Java Virtual Machine.<\/p>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435 &#8212; \u043a\u0430\u043a \u0440\u0430\u0437 \u0442\u043e, \u0447\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434 \u0441\u043b\u043e\u0432\u043e\u043c &#171;\u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f&#187;.<\/p>\n<h2>\u042d\u0440\u0437\u0430\u0446-\u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432 C++<\/h2>\n<p>\u0412 C++ \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u0443\u0441\u043e\u0447\u043a\u0438 &#171;\u044f\u0437\u044b\u043a\u043e\u0437\u043d\u0430\u043d\u0438\u044f&#187;, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043a\u043e\u0434\u0435 &#8212; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/types\/is_enum\" rel=\"noopener noreferrer nofollow\">std::is_enum<\/a> (compile-time), <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/typeid\" rel=\"noopener noreferrer nofollow\">typeid<\/a> (run-time).<\/p>\n<p>\u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043d\u0435\u0441\u0442\u0438 \u043a \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438, \u043d\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0441\u043f\u0430\u0440\u0442\u0430\u043d\u0441\u043a\u0438\u0439 \u0438 \u0434\u043b\u044f \u0432\u0435\u043b\u0438\u043a\u0438\u0445 \u0441\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0439 \u043d\u0435 \u0433\u043e\u0434\u0435\u043d. \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0437\u043d\u0430\u0435\u0442 \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u043f\u0440\u0438\u0441\u043f\u043e\u0441\u043e\u0431\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0438.<\/p>\n<h4>\u041a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0442\u0438\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h4>\n<p>\u041a \u044d\u0442\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 <a href=\"https:\/\/developers.google.com\/protocol-buffers\" rel=\"noopener noreferrer nofollow\">protobuf<\/a> &#8212; \u043c\u043e\u0434\u043d\u044b\u0439 &#171;\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c&#187; \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u0412 <code>.proto<\/code>-\u0444\u0430\u0439\u043b\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (<code>message Person<\/code>), \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u043b\u044f C++ \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0435\u0439 \u043a\u043b\u0430\u0441\u0441 (<code>class Person<\/code>) \u0441 \u0433\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438\/\u0441\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438, \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0435\u0437 \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0430 \u0438\u043c\u0435\u043d\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<p>\u0421\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u0432 \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 (\u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c, \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u043e \u0441\u0435\u0442\u0438), \u0438\u043b\u0438 \u0432 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f).<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0443 \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043a\u043e\u0440\u044f\u0447\u0438\u0442\u044c \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e protobuf \u0443\u0436\u0435 \u043d\u0430\u0431\u0438\u043b \u0432\u0441\u0435 \u0448\u0438\u0448\u043a\u0438 \u0437\u0430 \u043d\u0435\u0433\u043e.<\/p>\n<h4>\u0410\u0434\u0441\u043a\u0438\u0435 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u044b<\/h4>\n<p>\u041a \u044d\u0442\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/www.boost.org\/doc\/libs\/1_67_0\/libs\/hana\/doc\/html\/index.html\" rel=\"noopener noreferrer nofollow\">Boost.Hana<\/a>. \u0414\u043b\u044f \u043d\u0435\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0443\u0436\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">struct Person {   BOOST_HANA_DEFINE_STRUCT(Person,     (std::string, name),     (int, age)   ); };<\/code><\/pre>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441 &#171;\u0440\u0430\u0441\u043a\u0440\u043e\u0435\u0442\u0441\u044f&#187; \u0438 \u0432\u0441\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442. \u041f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 &#171;\u0434\u0435\u043c\u043e\u0441\u0446\u0435\u043d\u0443&#187; &#8212; \u0432\u044b\u0436\u0438\u043c\u0430\u044e\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0438\u0437 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0431\u044b\u043b \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d.<\/p>\n<h4>\u042d\u043a\u0441\u0442\u0440\u0435\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0437\u0430\u043b\u0430\u0437 \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440<\/h4>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0432\u0435\u0449\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b (\u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b\/\u0447\u0435\u043a\u0435\u0440\u044b\/etc.) \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a &#171;\u043f\u043b\u0430\u0433\u0438\u043d&#187; \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 AST (\u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430), \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/foonathan\/cppast\" rel=\"noopener noreferrer nofollow\">cppast<\/a>.<\/p>\n<p>AST \u044d\u0442\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043c\u0435\u0436\u0434\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0438 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043e\u043c. \u041a \u043d\u0435\u043c\u0443 \u043d\u0430\u0434\u043e \u043f\u0440\u0438\u0432\u044b\u043a\u043d\u0443\u0442\u044c, \u043d\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u0434\u0430 \u043d\u0430 C++. \u0415\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u0441\u043c\u043e\u0442\u0440\u0435\u043b \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 GCC \u0438\u043b\u0438 Clang, \u0442\u043e\u0442 \u0437\u043d\u0430\u0435\u0442, \u0447\u0442\u043e \u0441 \u043d\u0443\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u043c\u0430\u043b\u043e\u0440\u0435\u0430\u043b\u044c\u043d\u043e.<\/p>\n<h2>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u0432 C++<\/h2>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043c\u043d\u043e\u0433\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u043e\u0432, \u0433\u0434\u0435 \u0441 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432 <strong>run-time<\/strong>, \u0434\u0443\u0445 C++ \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0432 <strong>compile-time<\/strong>.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u044f\u0437\u044b\u043a \u0441\u0442\u0430\u0440\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 &#171;don\u2019t pay for what you don\u2019t use&#187;, \u0442\u043e ~95% \u0432\u0441\u0435\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u0430\u0440\u044f\u0435\u0442\u0441\u044f. \u0412 \u044f\u0437\u044b\u043a\u0435 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 \u0431\u0435\u0437 \u0440\u0430\u0437\u0434\u0443\u0432\u0430\u043d\u0438\u044f \u0431\u0438\u043d\u0430\u0440\u044f \u0447\u0435\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u043d\u0430\u0432\u0440\u043e\u0434\u0435 <a href=\"https:\/\/en.wikibooks.org\/wiki\/C%2B%2B_Programming\/RTTI\" rel=\"noopener noreferrer nofollow\">RTTI<\/a> (\u0441 \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043e\u0431\u044a\u0435\u043c\u043e\u043c).<\/p>\n<p>C++ \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0441\u0431\u043e\u0440\u043d\u0438\u043a \u0438\u0437 &#171;\u043f\u043e\u0434-\u044f\u0437\u044b\u043a\u043e\u0432&#187;, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 &#171;\u0443\u0440\u043e\u0432\u043d\u044f\u0445&#187;. \u0423\u0441\u043b\u043e\u0432\u043d\u043e\u0435 \u0434\u0435\u043b\u0435\u043d\u0438\u0435:<\/p>\n<ul>\n<li>\n<p><strong>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e C++<\/strong>: \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u0430\u043c\u044f\u0442\u044c\u044e, \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438, \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 (\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0441 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u041e\u0421), \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 <strong>run-time<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>\u0428\u0430\u0431\u043b\u043e\u043d\u044b<\/strong>: \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 (\u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f) \u0432 <strong>compile-time<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>Constexpr-\u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f<\/strong>: \u044d\u0442\u043e &#171;\u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0435&#187; \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e &#171;\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e C++&#187;, \u043e\u0442 \u0433\u043e\u0434\u0430 \u0432 \u0433\u043e\u0434 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u043d\u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 <a href=\"https:\/\/habr.com\/ru\/post\/579490\/\" rel=\"noopener noreferrer nofollow\">\u043c\u043e\u0435\u0439 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>. \u0412\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <strong>compile-time<\/strong> \u043f\u0440\u044f\u043c\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440<\/strong>: \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438 (\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438) \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432. \u0421 C++ \u0438\u043c\u0435\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0441\u0432\u044f\u0437\u044c, \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f Rust\/Java\/C#\/etc. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 &#171;\u043f\u043e\u0434-\u044f\u0437\u044b\u043a\u043e\u0432&#187; \u043d\u0435 \u0442\u044c\u044e\u0440\u0438\u043d\u0433-\u043f\u043e\u043b\u043d\u044b\u0439. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 <strong>compile-time<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0432 \u0432\u0438\u0434\u0435 \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043d\u044b\u0445 \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432 \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043e \u0438\u0437-\u0437\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u0442\u044c\u044e\u0440\u0438\u043d\u0433-\u043f\u043e\u043b\u043d\u043e\u0442\u044b. \u041e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0438\u043b\u0438 constexpr-\u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0432\u0432\u0435\u0441\u0442\u0438 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0439 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0435, \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e\u0442 \u0432\u0432\u0435\u0441\u0442\u0438 \u0432 constexpr-\u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0435 (\u0442\u0430\u043a \u043a\u0430\u043a \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 constexpr \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u043b\u0438\u0441\u044c).<\/p>\n<p>\u042f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043e\u0431\u0435\u0438\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432, \u0438 \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e <strong>\u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/strong> \u043a\u043e\u0434 \u0441 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c.<\/p>\n<h2>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445<\/h2>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u0440\u043e \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445 &#8212; pdf-\u043a\u0430 <a href=\"https:\/\/cplusplus.github.io\/reflection-ts\/draft.pdf\" rel=\"noopener noreferrer nofollow\">Reflection TS<\/a>, \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0435\u0441\u0442\u044c \u043d\u0430 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/experimental\/reflect\" rel=\"noopener noreferrer nofollow\">cppreference.com<\/a>.<\/p>\n<p>\u0421\u0432\u043e\u0439 \u043a\u043e\u0434 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 <a href=\"https:\/\/godbolt.org\/\" rel=\"noopener noreferrer nofollow\">godbolt.org<\/a>, \u0432\u044b\u0431\u0440\u0430\u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 <code>x86-64 clang (reflection)<\/code>.<\/p>\n<p>\u0412\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>reflexpr(X)<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e &#171;\u0441\u043a\u043e\u0440\u043c\u0438\u0442\u044c&#187; \u0432\u043c\u0435\u0441\u0442\u043e <code>X<\/code> \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e: \u0442\u0438\u043f, \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0438\u043c\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430, \u0438 \u0442.\u0434.<\/p>\n<p>\u042d\u0442\u043e\u0442 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u0435\u0440\u043d\u0435\u0442 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 <em>meta-object type<\/em> (\u0434\u0430\u043b\u0435\u0435 &#8212; \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0438\u043f&#187;), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043b\u044f \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u043c incomplete \u043a\u043b\u0430\u0441\u0441\u043e\u043c. \u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430:<\/p>\n<pre><code class=\"cpp\">enum Color {     Red, Green, Blue };  using MetaT = reflexpr(Color);<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0443 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u043e\u0432 (\u0432 <code>Reflection TS<\/code> \u0435\u0441\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u043e\u0432).<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>MetaT<\/code> \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0443 <code>reflect::Enum<\/code>, \u0438 \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 <code>reflect::Variable<\/code> &#8212; <a href=\"https:\/\/godbolt.org\/z\/Tf63PKEhG\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0434<\/a> \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439.<\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e &#171;\u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0439&#187; \u043e\u0434\u043d\u0438\u0445 \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445. \u0421\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u0438\u043c \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0430\u043c \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0438\u043f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>Reflection TS<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u043c <code>reflect::Enum<\/code> \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0442\u0438\u043f\u0430\u043c:<\/p>\n<pre><code class=\"cpp\">template &lt;Enum T> struct get_enumerators;  \/\/ \u0438 \u0435\u0433\u043e short-hand template &lt;Enum T> using get_enumerators_t = typename get_enumerators&lt;T>::type;<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f <code>get_enumerators_t&lt;MetaT><\/code> \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u0421 \u0435\u0435 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0434\u0440\u0443\u0433\u043e\u0439 \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0438\u043f, \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0439 \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0443 <code>reflect::ObjectSequence<\/code>.<\/p>\n<p>\u0412\u044b\u0432\u0435\u0434\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 <code>enum Color<\/code> \u0441\u043f\u0443\u0441\u0442\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">int main() {     constexpr std::string_view name = get_name_v&lt;get_element_t&lt;0, get_enumerators_t&lt;MetaT>>>;     std::cout &lt;&lt; \"The name of the first value is \\\"\" &lt;&lt; name &lt;&lt; \"\\\"\" &lt;&lt; std::endl; }<\/code><\/pre>\n<p><a href=\"https:\/\/godbolt.org\/z\/6Prs3fT1b\" rel=\"noopener noreferrer nofollow\">\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0434<\/a>.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043f\u0440\u0435\u0442\u0435\u043d\u0437\u0438\u044f \u043a \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u043c\u0443 \u043f\u043e\u0434\u0445\u043e\u0434\u0443 &#8212; \u043d\u0435\u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0441\u0442\u044c, \u043a\u0430\u043a \u043d\u0430\u0434\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434. \u041c\u044b \u0445\u043e\u0442\u0438\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0446\u0438\u043a\u043b \u043f\u043e <code>ObjectSequence<\/code>? \u041e\u0431\u044b\u0447\u043d\u044b\u043c for-\u043e\u043c \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f, \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u0437 \u043d\u0435\u0433\u043e, \u0438 \u043d\u0435\u043a\u0438\u0439 unpack_sequence:<\/p>\n<pre><code class=\"cpp\">template &lt;ObjectSequence T> struct get_size; template &lt;size_t I, ObjectSequence T> struct get_element; template &lt;template &lt;class...> class Tpl, ObjectSequence T>   struct unpack_sequence;<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443, \u043a\u0430\u043a \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e enum-\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043d\u0430\u0434\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u0436\u0443\u0442\u044c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e &#8212; <a href=\"https:\/\/gist.github.com\/Izaron\/290afdfc8af4ff81ceea11a10b2e57d4\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0434 \u0432 gist<\/a>.<\/p>\n<h2>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432 constexpr<\/h2>\n<p>\u042f\u0437\u044b\u043a \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0442 \u0436\u0438\u0432\u044b\u0435 \u043b\u044e\u0434\u0438, \u0443 \u043d\u0438\u0445 \u0442\u043e\u0436\u0435 \u0438\u0434\u0435\u0442 \u043a\u0440\u043e\u0432\u044c \u0438\u0437 \u0433\u043b\u0430\u0437 \u043f\u0440\u0438 \u0432\u0438\u0434\u0435 \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0439\u0447\u0430\u0441 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u0440\u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 &#8212; \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2021\/p2320r0.pdf\" rel=\"noopener noreferrer nofollow\">P2320<\/a>, \u0432\u0438\u0434\u0435\u043e-\u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 Andrew Sutton <a href=\"https:\/\/youtu.be\/60ECEc-URP8\" rel=\"noopener noreferrer nofollow\">\u043d\u0430 \u044e\u0442\u0443\u0431\u0435<\/a>, \u0438 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e <a href=\"https:\/\/github.com\/lock3\/meta\/wiki\/Reflection-Introductory-Tutorial\" rel=\"noopener noreferrer nofollow\">Wiki<\/a> \u0432 \u0433\u0438\u0442\u0445\u0430\u0431\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u0432\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 <code>^X<\/code> \u043f\u0435\u0440\u0435\u0434 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e <code>X<\/code>. \u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 constexpr-<strong>\u043e\u0431\u044a\u0435\u043a\u0442<\/strong> \u0442\u0438\u043f\u0430 <code>std::experimental::meta::info<\/code>.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0432 compile-time) \u043c\u043e\u0436\u043d\u043e &#171;\u0432\u0435\u0440\u043d\u0443\u0442\u044c&#187; \u0435\u0433\u043e \u0432 &#171;\u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439&#187; \u043c\u0438\u0440 \u0447\u0435\u0440\u0435\u0437 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>[:X:]<\/code> (\u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f &#171;splice&#187;). \u0417\u0430\u043f\u0438\u0441\u044c <code>[:^X:]<\/code> \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u0430 <code>X<\/code>.<\/p>\n<p>Andrew Sutton \u0432 \u0432\u0438\u0434\u0435\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0438\u0433\u0440\u0443\u0448\u0435\u0447\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0442\u0438\u043f\u0430 <code>T****...*<\/code> (\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0432\u0451\u0437\u0434\u043e\u0447\u0435\u043a \u0440\u0430\u0432\u043d\u043e N). \u0412\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u044b:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T, int N> auto make_indirect_template() {     if constexpr (N == 0) {         return T{};     } else {         return make_indirect_template&lt;T*, N - 1>();     } }<\/code><\/pre>\n<p>\u0410 \u0432\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e:<\/p>\n<pre><code class=\"cpp\">consteval meta::info make_pointer(meta::info type, int n) {     for (int i = 0; i &lt; n; ++i) {         type = meta::add_pointer(type);     }     return type; }  template&lt;typename T, int N> auto make_indirect_reflective() {     return typename [:make_pointer(^T, N):]{}; }<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 consteval-\u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432 compile-time. \u0412\u0441\u0435 consteval-\u043c\u0435\u0442\u043e\u0434\u044b \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 &#171;\u0438\u0441\u043f\u0430\u0440\u044f\u044e\u0442\u0441\u044f&#187;, \u0442\u043e \u0435\u0441\u0442\u044c \u0438\u0445 \u043a\u043e\u0434 \u0432 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0438\u043c\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0445\u0441\u044f \u0442\u0438\u043f\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">int main() {     auto ptr1 = make_indirect_template&lt;int, 42>();     std::cout &lt;&lt; meta::name_of(meta::type_of(^ptr1)) &lt;&lt; std::endl;      auto ptr2 = make_indirect_reflective&lt;int, 42>();     std::cout &lt;&lt; meta::name_of(meta::type_of(^ptr2)) &lt;&lt; std::endl; }<\/code><\/pre>\n<p><a href=\"https:\/\/cppx.godbolt.org\/z\/v5b7zP36Y\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043d\u0430 godbolt<\/a> <\/p>\n<h3>\u0421\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 \u043e \u0437\u0430\u043f\u0438\u0441\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432<\/h3>\n<p>\u0417\u0430\u043f\u0438\u0441\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 <code>^X<\/code> \u0438 <code>[:X:]<\/code> \u043c\u043e\u0433\u0443\u0442 \u043d\u0435 \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0438 \u0432\u0438\u0434\u043e\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442. \u041d\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0443\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0437\u0430\u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p>\u0420\u0430\u043d\u0435\u0435 \u0432\u043c\u0435\u0441\u0442\u043e <code>^X<\/code> \u0431\u044b\u043b <code>reflexpr(X)<\/code>, \u0432\u043c\u0435\u0441\u0442\u043e <code>[:X:]<\/code> \u0431\u044b\u043b <code>unreflexpr(X)<\/code>.<\/p>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439&#187;, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/cplusplus\/papers\/issues\/1002\" rel=\"noopener noreferrer nofollow\">github-\u0442\u0438\u043a\u0435\u0442\u0435 \u043f\u0440\u043e P2320<\/a>.<\/p>\n<h3>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a<\/h3>\n<p>\u0421\u0432\u043e\u0439 \u043a\u043e\u0434 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430 <a href=\"https:\/\/cppx.godbolt.org\/\" rel=\"noopener noreferrer nofollow\">cppx.godbolt.com<\/a>, \u0432\u044b\u0431\u0440\u0430\u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 <code>p2320 trunk<\/code>.<\/p>\n<p>\u042d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u0438 \u0431\u044b\u0441\u0442\u0440\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044e \u0447\u0435\u0440\u0435\u0437 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b. \u0412 \u043b\u0443\u0447\u0448\u0438\u0445 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u044f\u0445 \u0444\u043e\u0440\u043a \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443 <a href=\"https:\/\/github.com\/lock3\/meta\/wiki\/Build-Instructions\" rel=\"noopener noreferrer nofollow\">\u043f\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0441\u043e\u0437\u0434\u0430\u043b docker-\u043e\u0431\u0440\u0430\u0437.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0431\u043e\u0440\u043a\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c docker-\u043e\u0431\u0440\u0430\u0437\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>docker-\u043e\u0431\u0440\u0430\u0437 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u043f\u043e \u044d\u0442\u043e\u043c\u0443 <a href=\"https:\/\/gist.github.com\/Izaron\/b9cffc1270ecd102cf47d36e2f9b88a5\" rel=\"noopener noreferrer nofollow\">Dockerfile<\/a>, \u0441\u043e\u0431\u0438\u0440\u0430\u043b \u0432\u0435\u0442\u043a\u0443 <a href=\"https:\/\/github.com\/lock3\/meta\/tree\/paper\/p2320\" rel=\"noopener noreferrer nofollow\">paper\/p2320<\/a>.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c:<\/p>\n<pre><code>docker pull sehnsucht88\/clang-p2320<\/code><\/pre>\n<p>\u041f\u0443\u0441\u0442\u044c \u0432\u0430\u0448 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a <code>code.cpp<\/code> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>\/home\/username\/cpp<\/code>, \u0442\u043e\u0433\u0434\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code>docker run --rm -v \/home\/username\/cpp:\/cpp sehnsucht88\/clang-p2320 -std=c++2a -freflection -stdlib=libc++ \/cpp\/code.cpp -o \/cpp\/bin<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>\/home\/username\/cpp<\/code> \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u044b\u0439 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a <code><\/code><\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\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-326974","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/326974","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=326974"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/326974\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=326974"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=326974"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=326974"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}