{"id":111492,"date":"2025-08-21T07:00:00","date_gmt":"2025-08-21T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=111492"},"modified":"2025-08-15T16:13:18","modified_gmt":"2025-08-15T23:13:18","slug":"20250821-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20250821-00\/?p=111492","title":{"rendered":"Thoughts on creating a tracking pointer class, part 9: Conversion"},"content":{"rendered":"<p>Last time, we <a title=\"Thoughts on creating a tracking pointer class, part 8: Tracking const objects\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20250820-00\/?p=111490\"> added the ability to create tracking pointers from const objects<\/a>. But we discovered that you could not convert a <code>tracking_ptr&lt;T&gt;<\/code> to a <code>tracking_ptr&lt;const T&gt;<\/code>. But this should be possible, because the available operations on a tracking pointer to a const object is a subset of the operations available to a tracking pointer to a non-const object.<\/p>\n<p>We can perform the conversion by copying\/moving the underlying <code>tracking_<wbr \/>ptr_<wbr \/>base<\/code>.<\/p>\n<pre>template&lt;typename T&gt;\r\nstruct tracking_ptr : tracking_ptr_base&lt;std::remove_cv_t&lt;T&gt;&gt;\r\n{\r\n<span style=\"border: solid 1px currentcolor; border-bottom: none;\">private:                                                <\/span>\r\n<span style=\"border: solid 1px currentcolor; border-top: none;\">    using base = tracking_ptr_base&lt;std::remove_cv_t&lt;T&gt;&gt;;<\/span>\r\n\r\npublic:\r\n    T* get() const { return this-&gt;tracked; }\r\n\r\n    <span style=\"border: solid 1px currentcolor; border-bottom: none;\">using base::base;                                     <\/span>\r\n    <span style=\"border: 1px currentcolor; border-style: none solid;\">tracking_ptr(base const&amp; other) : base(other) {}      <\/span>\r\n    <span style=\"border: solid 1px currentcolor; border-top: none;\">tracking_ptr(base&amp;&amp; other) : base(std::move(other)) {}<\/span>\r\n};\r\n<\/pre>\n<p>If somebody has a <code>tracking_ptr&lt;T&gt;<\/code> it converts to a <code>tracking_ptr&lt;const T&gt;<\/code> by means of our two new constructors, which copy\/move the common <code>tracking_<wbr \/>ptr_<wbr \/>base&lt;T&gt;<\/code>, which is the thing that babysits the <code>shared_ptr&lt;T*&gt;<\/code>. To avoid repetitive typing, we make <code>base<\/code> an alias for the base class <code>tracking_ptr_base&lt;<wbr \/>std::remove_cv_t&lt;T&gt;&gt;<\/code>.<\/p>\n<p>We don&#8217;t need to write custom assignment operators because assignment can be performed by converting the <code>tracking_ptr&lt;T&gt;<\/code> to a <code>tracking_ptr&lt;const T&gt;<\/code>, and then assigning the <code>tracking_ptr&lt;const T&gt;<\/code>.<\/p>\n<p>But wait, there&#8217;s a problem with this. We&#8217;ll look at it next time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Making a read-only tracking pointer from a read-write tracking pointer.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-111492","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Making a read-only tracking pointer from a read-write tracking pointer.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/111492","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=111492"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/111492\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=111492"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=111492"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=111492"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}