{"id":35676,"date":"2025-08-19T16:35:10","date_gmt":"2025-08-19T16:35:10","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=35676"},"modified":"2025-08-19T16:35:10","modified_gmt":"2025-08-19T16:35:10","slug":"announcing-proxy-4-the-next-leap-in-c-polymorphism","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/announcing-proxy-4-the-next-leap-in-c-polymorphism\/","title":{"rendered":"Announcing Proxy 4: The Next Leap in C++ Polymorphism"},"content":{"rendered":"<p>Proxy 4 is here! After years of innovation and sustained use in the Windows OS codebase (since 2022), Proxy has matured from a bold experiment into a production-grade, modern C++ library for runtime polymorphism. The theory behind Proxy is original, and its design is now proven at scale. We are excited to invite the broader C++ community to join us in shaping the future of polymorphism. Your ideas and contributions are more welcome than ever!<\/p>\n<p>A special thank you to @SidneyCogdill for his outstanding contributions, especially for bringing support for C++20 modules to Proxy and driving major\u2011version compatibility efforts. His work has made the library even more accessible and future\u2011proof.<\/p>\n<h2>What is Proxy?<\/h2>\n<p>Proxy is a header-only, cross-platform C++20 library that lets you write polymorphic code without the pain of inheritance or the limitations of traditional virtual functions. Proxy enables you to:<\/p>\n<ul>\n<li>Write code that is portable, non-intrusive, and easy to maintain<\/li>\n<li>Manage object lifetimes flexibly, with or without ownership<\/li>\n<li>Achieve performance that rivals or exceeds hand-written code<\/li>\n<li>Compose abstractions from any expression: member functions, free functions, operators, conversions, and more<\/li>\n<\/ul>\n<p>If you&#8217;re new to Proxy, check out our <a href=\"https:\/\/github.com\/microsoft\/proxy\">GitHub repository<\/a> and our previous announcements: <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/announcing-the-proxy-3-library-for-dynamic-polymorphism\/\">Announcing the Proxy 3 Library for Dynamic Polymorphism<\/a> and <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/analyzing-the-performance-of-the-proxy-library\/\">Analyzing the Performance of the &#8220;Proxy&#8221; Library<\/a>.<\/p>\n<h2>New Website: Your One-Stop Reference<\/h2>\n<p>We&#8217;ve launched a new documentation website, built with MkDocs, to help you find everything you need about Proxy. The new site offers improved navigation, a unified FAQ, and a clear structure for all features and APIs. Explore the <a href=\"https:\/\/microsoft.github.io\/proxy\/\">documentation<\/a> and discover how easy it is to get started!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2025\/08\/index.png\" alt=\"Index\" \/><\/p>\n<h2>Try Proxy Instantly in Compiler Explorer<\/h2>\n<p>You can now experiment with Proxy directly in your browser using <a href=\"https:\/\/godbolt.org\/z\/E95nY7PYq\">Compiler Explorer<\/a>! Write, run, and inspect Proxy code without any setup. Just click on &#8220;Libraries&#8221; and search for &#8220;proxy&#8221; in Compiler Explorer or use a shared link from our examples to get started. It&#8217;s a great way to see Proxy in action and share your findings with others.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2025\/08\/compiler-explorer.png\" alt=\"Compiler Explorer\" \/><\/p>\n<h2>What&#8217;s New in Proxy 4?<\/h2>\n<h3>Skills: Composable Facade Capabilities<\/h3>\n<p>Let&#8217;s see how easy it is to add formatting support to your types (<a href=\"https:\/\/godbolt.org\/z\/3G363xz71\">run in Compiler Explorer<\/a>):<\/p>\n<pre><code class=\"language-cpp\">#include &lt;format&gt;\r\n#include &lt;proxy\/proxy.h&gt;\r\n\r\nstruct Formattable : pro::facade_builder\r\n    ::add_skill&lt;pro::skills::format&gt;\r\n    ::build {};\r\n\r\nint main() {\r\n  pro::proxy&lt;Formattable&gt; p = pro::make_proxy&lt;Formattable&gt;(123);\r\n  std::cout &lt;&lt; std::format(\"{}\\n\", *p); \/\/ Prints \"123\"\r\n}<\/code><\/pre>\n<p>Skills are reusable building blocks that let you add powerful capabilities to your facades with a single line:<\/p>\n<ul>\n<li><a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/skills_format\/\"><code>skills::format<\/code> and <code>skills::wformat<\/code><\/a>: Enable standard C++ formatting for your proxies. This was never possible with virtual functions or earlier Proxy versions.<\/li>\n<li><a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/skills_fmt_format\/\"><code>skills::fmt_format<\/code> and <code>skills::fmt_wformat<\/code><\/a>: Bring full <a href=\"https:\/\/github.com\/fmtlib\/fmt\">{fmt} library<\/a> support to your proxies, letting you use advanced formatting features with zero boilerplate.<\/li>\n<li><a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/skills_rtti\/\"><code>skills::rtti<\/code><\/a>: Add runtime type information and safe casting to your proxies.<\/li>\n<li><a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/skills_as_view\/\"><code>skills::as_view<\/code><\/a> and <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/skills_as_weak\/\"><code>skills::as_weak<\/code><\/a>: Allow seamless conversion to non-owning or weak proxies, making your code safer and more expressive.<\/li>\n<li><a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/skills_slim\/\"><code>skills::slim<\/code><\/a>: Restrict your proxy to pointer-sized storage for maximum efficiency.<\/li>\n<\/ul>\n<p>Skills are easy to compose and extend. You can also author internal, domain\u2011specific skills to capture patterns (logging, metrics hooks, validation, instrumentation) so teams reuse a single, well-reviewed definition instead of duplicating conventions. This improves consistency and long\u2011term maintainability. See the <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/basic_facade_builder\/add_skill\/\">skills documentation<\/a> for more.<\/p>\n<h3>Easy Borrowing and Weak References<\/h3>\n<p>Proxy 4 introduces convenient aliases for non-owning and weak references: <code>proxy_view<\/code> and <code>weak_proxy<\/code>. These are built on top of the core <code>proxy<\/code> concept, making it easier to express borrowing and weak ownership patterns in your code. For example, you can use <code>proxy_view<\/code> to safely borrow an object without taking ownership, or <code>weak_proxy<\/code> to create a weak reference that can be locked when needed. See the <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/proxy_view\/\"><code>proxy_view<\/code> documentation<\/a> and <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/weak_proxy\/\"><code>weak_proxy<\/code> documentation<\/a> for details.<\/p>\n<h3>Shared Ownership Made Simple<\/h3>\n<p>With the new <code>make_proxy_shared<\/code> and <code>allocate_proxy_shared<\/code> APIs, you can create shared and weak proxies efficiently, without the overhead of <code>std::shared_ptr<\/code>. These APIs use compact internal pointer types, ensuring high performance and low memory usage. Learn more in the <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/make_proxy_shared\/\"><code>make_proxy_shared<\/code> documentation<\/a> and <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/allocate_proxy_shared\/\"><code>allocate_proxy_shared<\/code> documentation<\/a>.<\/p>\n<h2>Smarter Dispatch and Conversion<\/h2>\n<ul>\n<li><a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/weak_dispatch\/\"><code>weak_dispatch<\/code><\/a> lets you define fallback behavior for missing conventions, so your code can handle incomplete types gracefully.<\/li>\n<li>Conversion dispatches (<a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/explicit_conversion_dispatch\/\"><code>explicit_conversion_dispatch<\/code><\/a>, <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/implicit_conversion_dispatch\/\"><code>implicit_conversion_dispatch<\/code><\/a>) are now easier to use and provide clearer error messages.<\/li>\n<li>The new <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/proxiable_target\/\"><code>proxiable_target<\/code><\/a> and <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/inplace_proxiable_target\/\"><code>inplace_proxiable_target<\/code><\/a> concepts make it clear which target types can be used with a given facade, helping you avoid surprises and write safer code.<\/li>\n<\/ul>\n<h2>Recursive Facade Patterns Made Easy<\/h2>\n<p>Proxy 4 introduces <code>facade_aware_overload_t<\/code>, which lets you define recursive conventions that refer to the facade itself without forcing early instantiation. This is especially useful for operator chaining patterns (like arithmetic or concatenation) that return new <code>proxy<\/code> objects of the same facade. Example:<\/p>\n<pre><code class=\"language-cpp\">#include &lt;format&gt;\r\n#include &lt;iostream&gt;\r\n#include &lt;proxy\/proxy.h&gt;\r\n\r\ntemplate &lt;class F&gt;\r\nusing BinaryOverload =\r\n    pro::proxy&lt;F&gt;(const pro::proxy_indirect_accessor&lt;F&gt;&amp; rhs) const;\r\n\r\ntemplate &lt;class T, pro::facade F&gt;\r\npro::proxy&lt;F&gt; operator+(const T&amp; value,\r\n                        const pro::proxy_indirect_accessor&lt;F&gt;&amp; rhs)\r\n  requires(!std::is_same_v&lt;T, pro::proxy_indirect_accessor&lt;F&gt;&gt;)\r\n{\r\n  return pro::make_proxy&lt;F, T&gt;(value + proxy_cast&lt;const T&amp;&gt;(rhs));\r\n}\r\n\r\nstruct Addable\r\n    : pro::facade_builder              \/\/ Compose capabilities\r\n      ::add_skill&lt;pro::skills::rtti&gt;   \/\/ RTTI support\r\n      ::add_skill&lt;pro::skills::format&gt; \/\/ Formatting support\r\n      ::add_convention&lt;pro::operator_dispatch&lt;\"+\"&gt;,\r\n                       pro::facade_aware_overload_t&lt;BinaryOverload&gt;&gt; \/\/ Recursive operator\r\n      ::build {};\r\n\r\nint main() {\r\n  pro::proxy&lt;Addable&gt; p1 = pro::make_proxy&lt;Addable&gt;(1);\r\n  pro::proxy&lt;Addable&gt; p2 = pro::make_proxy&lt;Addable&gt;(2);\r\n  pro::proxy&lt;Addable&gt; p3 = *p1 + *p2; \/\/ Uses facade-aware overload\r\n  std::cout &lt;&lt; std::format(\"{}\\n\", *p3); \/\/ Prints \"3\"\r\n}<\/code><\/pre>\n<p>See the <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/facade_aware_overload_t\/\"><code>facade_aware_overload_t<\/code> documentation<\/a> for details.<\/p>\n<h2>Quality Improvements for Everyone<\/h2>\n<ul>\n<li><strong>Bitwise Trivially Relocatable<\/strong>: Proxy now supports types that can be moved with <code>memcpy<\/code>, enabling faster moves and assignments by default. This means better performance and less boilerplate for you. See the <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/is_bitwise_trivially_relocatable\/\"><code>is_bitwise_trivially_relocatable<\/code> documentation<\/a> for more details.<\/li>\n<li><strong>C++20 Modules Support<\/strong>: Thanks to @SidneyCogdill, Proxy now ships with <code>.ixx<\/code> files for blazing-fast builds and better IDE support.<\/li>\n<li><strong>Diagnostics<\/strong>: Error messages are now much clearer and more actionable, helping you quickly understand and fix issues in your code.<\/li>\n<li><strong>Debugging Experience<\/strong>: Proxy 4 generates better debugging symbols, making it easier to inspect proxies in your debugger and understand what&#8217;s happening under the hood.<\/li>\n<li><strong>Accessibility Authoring<\/strong>: It&#8217;s now easier to expose reflection and dispatch capabilities in your facades, with less boilerplate and more flexibility.<\/li>\n<li><strong>Code Generation<\/strong>: Proxy 4 refines the call path for indirect dispatch, reducing the number of instructions around indirect calls.<\/li>\n<li><strong>Compiler Support<\/strong>: NVIDIA HPC is newly added to our supported toolchains. Proxy 4 passes tests on the latest GCC, Clang, MSVC, and NVIDIA HPC compilers. We&#8217;re committed to keeping Proxy working with these compilers going forward, including freestanding environments. See the <a href=\"https:\/\/github.com\/microsoft\/proxy#compiler-req\">README<\/a> for minimum versions and flags.<\/li>\n<\/ul>\n<h2>Major Version Compatibility<\/h2>\n<p>Upgrading a small component is usually straightforward, but migrating a monorepo or multi-module product can be challenging. Follow the guidelines below:<\/p>\n<ol>\n<li><strong>Minor or patch upgrades (e.g. 3.3.0 \u2192 3.4.0)<\/strong>\nAll 3.x.y releases preserve API\/ABI compatibility, so different parts of the program may safely depend on different 3.x.y versions. No special action is required.<\/li>\n<li><strong>Major upgrades (e.g. 3.4.0 \u2192 4.0.0)<\/strong>\n<ul>\n<li>If your current version is <em>earlier<\/em> than 3.4.0, migrate to 3.4.0 first.<\/li>\n<li>Starting with 3.4.0, each major release is placed in a versioned inline namespace (<code>pro::v3<\/code>, <code>pro::v4<\/code>, \u2026).\u00a0 When a translation unit sees multiple majors, qualify the namespace explicitly:\n<pre><code class=\"language-cpp\">pro::v3::foo(); \/\/ Proxy 3 API\r\npro::v4::foo(); \/\/ Proxy 4 API<\/code><\/pre>\n<p>The newest release re-exports its namespace as the inline (default) namespace, so unqualified calls (<code>pro::foo()<\/code>) resolve to the latest version once the migration is complete.<\/li>\n<li>The macros also have major-qualified aliases, e.g. <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/PRO_DEF_MEM_DISPATCH\/\"><code>PRO4_DEF_MEM_DISPATCH<\/code><\/a>. Use these forms whenever headers from multiple majors are included in the same translation unit.<\/li>\n<li>Upgrade subsystems incrementally, module-by-module or DLL-by-DLL. When every target depends only on the new major, drop the old include path and remove the previous version from your build.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>These rules let old and new code coexist during the transition while keeping ODR violations at bay.<\/p>\n<h2>Other Notable Changes<\/h2>\n<ul>\n<li>The macro <code>PRO_DEF_WEAK_DISPATCH<\/code> has been removed in favor of the more flexible <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/weak_dispatch\/\"><code>weak_dispatch<\/code><\/a> class.<\/li>\n<li>The class <code>proxiable_ptr_constraints<\/code> has been merged into the <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/ProFacade\/\"><em>ProFacade<\/em> requirements<\/a> for simplicity.<\/li>\n<li>The function template <code>access_proxy<\/code> is now shadowed by <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/proxy_invoke\/\"><code>proxy_invoke<\/code><\/a> and <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/proxy_reflect\/\"><code>proxy_reflect<\/code><\/a>.<\/li>\n<li>The <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/ProFacade\/\"><em>ProFacade<\/em><\/a> and <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/ProDispatch\/\"><em>ProDispatch<\/em> requirements<\/a> have been revised for clarity and consistency.<\/li>\n<\/ul>\n<h2>Summary<\/h2>\n<p>Proxy 4 builds on a mature foundation introduced and proven in Proxy 3, and adds focused refinements rather than reinventing the model.<\/p>\n<p>Core capabilities (established in Proxy 3 and still central in day\u2011to\u2011day use):<\/p>\n<ul>\n<li>Expression\u2011based polymorphism: define a facade once, make virtually any expression (member calls, free calls, operators, explicit\/implicit conversions) polymorphic.<\/li>\n<li>Flexible creation: <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/make_proxy\/\"><code>make_proxy<\/code><\/a> (inline where possible), <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/allocate_proxy\/\"><code>allocate_proxy<\/code><\/a> (custom allocators), raw pointer attachment, unique ownership, and composition of abstractions via <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/basic_facade_builder\/add_convention\/\"><code>add_convention<\/code><\/a> \/ <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/basic_facade_builder\/add_reflection\/\"><code>add_reflection<\/code><\/a> \/ <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/basic_facade_builder\/add_facade\/\"><code>add_facade<\/code><\/a>.<\/li>\n<li>Lifetime versatility in a single <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/proxy\/\"><code>proxy<\/code><\/a> type: same facade supports non\u2011owning, unique, inline, or externally managed objects transparently.<\/li>\n<li>Overload resolution &amp; reflection support for concise, generic call sites.<\/li>\n<\/ul>\n<p>Targeted Proxy 4 refinements:<\/p>\n<ul>\n<li>Ergonomic aliases for borrowing \/ weak observation (<a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/proxy_view\/\"><code>proxy_view<\/code><\/a>, <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/weak_proxy\/\"><code>weak_proxy<\/code><\/a>) built atop the existing core.<\/li>\n<li>Skill-based composition (formatting, RTTI, view\/weak conversion, slim layout, {fmt} integration) to replace repetitive convention boilerplate.<\/li>\n<li>New shared\/weak creation helpers (<a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/make_proxy_shared\/\"><code>make_proxy_shared<\/code><\/a>, <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/allocate_proxy_shared\/\"><code>allocate_proxy_shared<\/code><\/a>) complement (not replace) the more frequently used <code>make_proxy<\/code> \/ <code>allocate_proxy<\/code> paths.<\/li>\n<li>Concepts (<a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/proxiable_target\/\"><code>proxiable_target<\/code><\/a>, <a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/inplace_proxiable_target\/\"><code>inplace_proxiable_target<\/code><\/a>) clarify when a type can be used with <code>make_proxy<\/code> versus <code>make_proxy_inplace<\/code>, giving earlier, sharper diagnostics instead of template noise.<\/li>\n<li><a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/facade_aware_overload_t\/\"><code>facade_aware_overload_t<\/code><\/a> enables recursive facade\/operator definitions (e.g. arithmetic that returns the same facade) without forcing premature instantiation.<\/li>\n<li><a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/weak_dispatch\/\"><code>weak_dispatch<\/code><\/a> for graceful fallback when some contained types omit a convention.<\/li>\n<li>Improved diagnostics, relocation optimizations (<a href=\"https:\/\/microsoft.github.io\/proxy\/spec\/is_bitwise_trivially_relocatable\/\"><code>is_bitwise_trivially_relocatable<\/code><\/a>), module support, and leaner code generation.<\/li>\n<\/ul>\n<p>Questions and feedback are welcome! If you find something unclear, a bug, or a documentation gap, feel free to open an issue or submit a PR.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Version 4 of Microsoft&#8217;s Proxy library brings feature improvements, better diagnostics, better code generation, modern compiler\/debugger support.<\/p>\n","protected":false},"author":98503,"featured_media":35677,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[270,1],"tags":[],"class_list":["post-35676","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcement","category-cplusplus"],"acf":[],"blog_post_summary":"<p>Version 4 of Microsoft&#8217;s Proxy library brings feature improvements, better diagnostics, better code generation, modern compiler\/debugger support.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/35676","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/98503"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=35676"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/35676\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35677"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=35676"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=35676"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=35676"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}