{"id":2503,"date":"2012-04-06T09:33:00","date_gmt":"2012-04-06T09:33:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2012\/04\/06\/what-are-scary-iterators\/"},"modified":"2021-10-04T10:55:34","modified_gmt":"2021-10-04T10:55:34","slug":"what-are-scary-iterators","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/what-are-scary-iterators\/","title":{"rendered":"What Are SCARY Iterators?"},"content":{"rendered":"<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2012\/04\/8880.diegum_thumb_2AB0555D.jpg\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2012\/04\/8880.diegum_thumb_2AB0555D.jpg\" alt=\"Image 8880 diegum thumb 2AB0555D\" width=\"91\" height=\"91\" class=\"alignleft size-full wp-image-29029\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2012\/04\/8880.diegum_thumb_2AB0555D.jpg 91w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2012\/04\/8880.diegum_thumb_2AB0555D-24x24.jpg 24w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2012\/04\/8880.diegum_thumb_2AB0555D-48x48.jpg 48w\" sizes=\"(max-width: 91px) 100vw, 91px\" \/><\/a><\/p>\n<p>Hi there! I&rsquo;m Diego Dagum, a Program Manager with the Visual C++ team.<\/p>\n<p>As <a href=\"http:\/\/blogs.msdn.com\/b\/vcblog\/archive\/2011\/09\/12\/10209291.aspx\" target=\"_blank\" rel=\"noopener\">Stephan announced last September when Visual Studio 11 Developer Preview was released<\/a>, our STL implementation comes with <strong>SCARY iterators<\/strong>. On Stephan&rsquo;s words,<\/p>\n<blockquote>\n<p>&rdquo;(&hellip;) as permitted but not required by the C++11 Standard, SCARY iterators have been implemented, as described by <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/WG21\/docs\/papers\/2009\/n2911.pdf\" target=\"_blank\" rel=\"noopener\">N2911 &#8220;<em>Minimizing Dependencies within Generic Classes for Faster and Smaller Programs<\/em>&#8220;<\/a> and <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/WG21\/docs\/papers\/2009\/n2980.pdf\" target=\"_blank\" rel=\"noopener\">N2980 &#8220;<em>SCARY Iterator Assignment and Initialization, Revision 1<\/em>&rdquo;<\/a>.<\/p>\n<\/blockquote>\n<p>What are they useful for? What are they, in the first place? What&rsquo;s so SCARY about them?<\/p>\n<p>In this post I&rsquo;ll demystify any mystery about SCARY iterators, hopefully inspiring in you some design best practice for your own template classes.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Imagine the following situation:<\/p>\n<div class=\"wlWriterEditableSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6228bcc4-224d-4091-90de-7735967ff0af\" style=\"float: none;margin: 0px;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li><span style=\"background: #ffffff;color: #008000\">\/\/ the list below uses an allocator other than the default<\/span><\/li>\n<li style=\"background: #f3f3f3\"><span style=\"background: #ffffff;color: #2b91af\">list<\/span><span style=\"background: #ffffff;color: #000000\">&lt;<\/span><span style=\"background: #ffffff;color: #0000ff\">int<\/span><span style=\"background: #ffffff;color: #000000\">, stdext::allocators::<\/span><span style=\"background: #ffffff;color: #2b91af\">allocator_unbounded<\/span><span style=\"background: #ffffff;color: #000000\">&lt;<\/span><span style=\"background: #ffffff;color: #0000ff\">int<\/span><span style=\"background: #ffffff;color: #000000\">&gt;&gt; l;<\/span><\/li>\n<li>&nbsp;<\/li>\n<li style=\"background: #f3f3f3\"><span style=\"background: #ffffff;color: #008000\">\/\/ Is the following line valid? (i.e. does it compile?)<\/span><\/li>\n<li><span style=\"background: #ffffff;color: #2b91af\">list<\/span><span style=\"background: #ffffff;color: #000000\">&lt;<\/span><span style=\"background: #ffffff;color: #0000ff\">int<\/span><span style=\"background: #ffffff;color: #000000\">&gt;::<\/span><span style=\"background: #ffffff;color: #2b91af\">iterator<\/span><span style=\"background: #ffffff;color: #000000\"> iter(l.begin());<\/span><\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Does it compile or not? Well, I tried to compile that code using a pre-v11 Visual C++ compiler, getting the following error:<\/p>\n<div class=\"wlWriterEditableSmartContent\" id=\"scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0ea8b85e-f598-4c06-b654-2792c7cbb4fc\" style=\"float: none;margin: 0px;padding: 0px\">\n<div style=\"border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt\">\n<div style=\"background: #fff;overflow: auto\">\n<ol style=\"background: #ffffff;margin: 0;padding: 0 0 0 5px\">\n<li>error C2664: &#8216;std::_List_iterator&lt;_Mylist&gt;::_List_iterator(const std::_List_iterator&lt;_Mylist&gt; &amp;)&#8217; : cannot convert parameter 1 from &#8216;std::_List_iterator&lt;_Mylist&gt;&#8217; to &#8216;const std::_List_iterator&lt;_Mylist&gt; &amp;&#8217;<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Mylist=std::_List_val&lt;int,std::allocator&lt;int&gt;&gt;<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;and<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Mylist=std::_List_val&lt;int,stdext::allocators::allocator_unbounded&lt;int&gt;&gt;<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;and<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Mylist=std::_List_val&lt;int,std::allocator&lt;int&gt;&gt;<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reason: cannot convert from &#8216;std::_List_iterator&lt;_Mylist&gt;&#8217; to &#8216;const std::_List_iterator&lt;_Mylist&gt;&#8217;<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Mylist=std::_List_val&lt;int,stdext::allocators::allocator_unbounded&lt;int&gt;&gt;<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;and<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Mylist=std::_List_val&lt;int,std::allocator&lt;int&gt;&gt;<\/li>\n<li style=\"background: #f3f3f3\">1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<\/li>\n<li>1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The reason I&rsquo;ve got this error is that in the last line of the code I&rsquo;m trying to initialize <span style=\"font-family: Courier New\">iter<\/span> (an iterator over a list of <span style=\"font-family: Courier New\">int<\/span> using the default list allocator <span style=\"font-family: Courier New\">std::allocator&lt;<span style=\"color: #0000ff\">int<\/span>&gt;<\/span>) with an iterator which looks similar excepts that it corresponds to a list allocated by the alternative <span style=\"font-family: Courier New\">stdext::allocators::allocator_unbounded&lt;<span style=\"color: #0000ff\">int<\/span>&gt;<\/span>. Sad but true, these are different specializations of list of <span style=\"font-family: Courier New\">int<\/span>s; therefore, conversions between them can&rsquo;t be handled by default.<\/p>\n<p>From a compiler perspective there is nothing wrong here. From a practical standpoint, however, there isn&rsquo;t any semantic dependence between list iterators and list allocators. And, in general for all STL containers, iterators only depend (semantically speaking) on the container element type.<\/p>\n<p>Based on research paper <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/WG21\/docs\/papers\/2009\/n2911.pdf\" target=\"_blank\" rel=\"noopener\">N2911<\/a> &#8220;<em>Minimizing Dependencies within Generic Classes for Faster and Smaller Programs<\/em>&#8220;, the acronym SCARY describes<\/p>\n<blockquote>\n<p><em>Assignments and initializations that are <\/em><span style=\"font-size: large\">S<\/span><em>eemingly erroneous (appearing <\/em><span style=\"font-size: large\">C<\/span><em>onstrained by conflicting generic parameters), but <\/em><span style=\"font-size: large\">A<\/span><em>ctually work with the <\/em><span style=\"font-size: large\">R<\/span><em>ight implementation (unconstrained b<\/em><span style=\"font-size: large\">Y<\/span><em> the conflict due to minimized dependencies)<\/em><\/p>\n<\/blockquote>\n<p>&hellip; or just SCARY, you know&#8230; (Don&rsquo;t kill the messenger, I wasn&rsquo;t the inventor of this name!)<\/p>\n<p>&nbsp;<\/p>\n<p>In our STL11 implementation, iterator dependencies were minimized so the precedent code compiles fine. The same applies for any other STL container iterator (vector, deque, etc.) This said, you&rsquo;ll be able to implement novel algorithms in ways that were previously impossible due to type mismatches. Not that scary, after all!<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h2>Epilogue<\/h2>\n<p>The issue that prevented my program to compile isn&rsquo;t just tied to a particular&nbsp;STL implementation. In fact, as <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/WG21\/docs\/papers\/2009\/n2911.pdf\" target=\"_blank\" rel=\"noopener\">N2911 &#8220;<em>Minimizing Dependencies within Generic Classes for Faster and Smaller Programs<\/em>&#8220;<\/a> tells, it&#8217;s a more general issue that can happen when designing generic classes. In its authors&rsquo; own words:<\/p>\n<blockquote>\n<p><em>We advocate a design principle whereby the dependencies between the members and the type parameters of a generic class should be minimized, we propose techniques to realize this principle, and we show that the principle can be leveraged to achieve faster and smaller programs.<\/em><\/p>\n<\/blockquote>\n<p>Worth reading. Enjoy!<\/p>\n<p>&nbsp;<\/p>\n<p>PS. A HUGE THANKS to Stephan T. Lavavej (Mr. STL) for reviewing this post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi there! I&rsquo;m Diego Dagum, a Program Manager with the Visual C++ team. As Stephan announced last September when Visual Studio 11 Developer Preview was released, our STL implementation comes with SCARY iterators. On Stephan&rsquo;s words, &rdquo;(&hellip;) as permitted but not required by the C++11 Standard, SCARY iterators have been implemented, as described by N2911 [&hellip;]<\/p>\n","protected":false},"author":293,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[68,32],"class_list":["post-2503","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-design","tag-stl"],"acf":[],"blog_post_summary":"<p>Hi there! I&rsquo;m Diego Dagum, a Program Manager with the Visual C++ team. As Stephan announced last September when Visual Studio 11 Developer Preview was released, our STL implementation comes with SCARY iterators. On Stephan&rsquo;s words, &rdquo;(&hellip;) as permitted but not required by the C++11 Standard, SCARY iterators have been implemented, as described by N2911 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/2503","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\/293"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=2503"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/2503\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=2503"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=2503"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=2503"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}