{"id":1716,"date":"2024-08-20T15:24:17","date_gmt":"2024-08-20T22:24:17","guid":{"rendered":"http:\/\/75.119.134.73\/?p=1716"},"modified":"2024-08-20T15:24:17","modified_gmt":"2024-08-20T22:24:17","slug":"use-span-to-avoid-vector-of-pointers","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2024\/08\/20\/use-span-to-avoid-vector-of-pointers\/","title":{"rendered":"Use Span to Avoid Vector of Pointers"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">#include &lt;charconv>\n#include &lt;future>\n#include &lt;iostream>\n#include &lt;sstream>\n#include &lt;string>\n#include &lt;string_view>\n#include &lt;variant>\n#include &lt;vector>\n#include &lt;unordered_set>\n#include &lt;span>\n\nstruct MyStruct {\n  std::unordered_set&lt;int> s;\n  MyStruct() {\n    std::cout &lt;&lt; \"constructor\\n\";\n  }\n\n  MyStruct(const MyStruct&amp; other) {\n    std::cout &lt;&lt; \"copy constructor\\n\";\n    this->s = other.s;\n  }\n\n  MyStruct&amp; operator=(const MyStruct&amp; other) {\n    std::cout &lt;&lt; \"copy assignment\\n\";\n    this->s = other.s;\n    return *this;\n  }\n\n  MyStruct(MyStruct&amp;&amp; other) {\n    std::cout &lt;&lt; \"move constructor\\n\";\n    this->s = other.s;\n  }\n  MyStruct&amp; operator=(MyStruct&amp;&amp; other) {\n    std::cout &lt;&lt; \"move assignment\\n\";\n    this->s = std::move(other.s);\n    return *this;\n  }\n};\n\nstruct Holder {\n  Holder() : structs{MyStruct(), MyStruct()} {}\n  const std::vector&lt;MyStruct> structs;\n};\n\nvoid PrintStructs(std::span&lt;const MyStruct> my_structs)\n{\n  for (const MyStruct&amp; s : my_structs) {\n    std::cout &lt;&lt; \"iterate on a struct\\n\";\n  } \n}\n\nint main()\n{\n    Holder holder;\n    std::cout &lt;&lt; \"holder created\\n\";\n    PrintStructs(holder.structs);\n    return 0;\n}\n\n<\/code><\/pre>\n\n\n\n<p>Consider the above code. <code>PrintStructs<\/code> will not copy structs at all but still guarantee the constness of <code>MyStruct<\/code> <\/p>\n\n\n\n<p>Constness is especially important. Consider the following awkward situation when you deal with vector of pointers.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">struct Foo {\n  void SomeNonConstOp() {}\n};\n\nclass MyClass {\n public:\n  \/\/ This is supposed to be const.\n  \/\/ Don\u2019t modify my Foos, pretty please.\n  const std::vector&lt;Foo*>&amp; shallow_foos() const { return foos_; }\n  \/\/ Really deep const.\n  std::span&lt;const Foo* const> deep_foos() const { return foos_; }\n\n  \/\/ Does not compile\n  \/\/ main.cpp:74:34: error: \u2018const std::vector&amp; MyClass::shallow_foos() const\u2019 cannot be overloaded with \u2018const std::vector&amp; MyClass::shallow_foos() const\u2019\n  \/\/ const std::vector&lt;const Foo*>&amp; shallow_foos() const { return foos_; }   \n\n private:\n  std::vector&lt;Foo*> foos_;\n};\nvoid Caller(const MyClass* my_class) {\n  \/\/ Accidental violation of MyClass::shallow_foos() contract.\n  my_class->shallow_foos()[0]->SomeNonConstOp();\n  \/\/ This one doesn't compile.\n  \/\/ my_class->deep_foos()[0]->SomeNonConstOp();\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Consider the above code. PrintStructs will not copy structs at all but still guarantee the constness of MyStruct Constness is especially important. Consider the following awkward situation when you deal with vector of pointers.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"0","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1716","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1716","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=1716"}],"version-history":[{"count":1,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1716\/revisions"}],"predecessor-version":[{"id":1718,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1716\/revisions\/1718"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=1716"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=1716"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=1716"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}