{"id":102816,"date":"2019-08-29T07:00:00","date_gmt":"2019-08-29T14:00:00","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/oldnewthing\/?p=102816"},"modified":"2019-08-29T06:29:15","modified_gmt":"2019-08-29T13:29:15","slug":"20190829-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190829-00\/?p=102816","title":{"rendered":"On resolving the type vs member conflict in C++, revisited"},"content":{"rendered":"<p>Some time ago, I wrote about <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190419-00\/?p=102431\"> the type vs. member conflict<\/a>, known informally as <i>The Color Color problem<\/i>. I may have started in the deep end of the pool, so here&#8217;s a little bit of getting-up-to-speed so that article might make more sense.<\/p>\n<pre>namespace Windows::UI::Xaml\r\n{\r\n  enum class Visibility { Collapsed, Visible };\r\n\r\n  struct Style { \/* ... *\/ };\r\n\r\n  namespace Controls\r\n  {\r\n    struct UIElement\r\n    {\r\n    public:\r\n      \/* ... *\/\r\n\r\n      \/\/ returns current visibility\r\n      Windows::UI::Xaml::Visibility Visibility();\r\n\r\n      \/\/ change visibility\r\n      void Visibility(Windows::UI::Xaml::Visibility value);\r\n\r\n      \/\/ returns current style\r\n      Windows::UI::Xaml::Style Style();\r\n\r\n      \/\/ change style\r\n      void Style(Windows::UI::Xaml::Style value);\r\n    };\r\n  }\r\n}\r\n<\/pre>\n<p>The fundamental problem here is that there is a name conflict between the type <code>Style<\/code> and the method <code>Style<\/code>. There is also a name conflict between the type <code>Visibility<\/code> and the method <code>Visibility<\/code>.<\/p>\n<p>When used from within the <code>UIElement<\/code> class, or any class derived from it, the names <code>Style<\/code> and <code>Visibility<\/code> refer to the methods <code>UIElement::<\/code><code>Style<\/code> and <code>UIElement::<\/code><code>Visibility<\/code>, rather than to the types.<\/p>\n<p>In language-speak, these are <i>unqualified names<\/i>, meaning that the name is just hanging out by itself without any clues as to where to find it. You&#8217;re asking the compiler to figure out what you&#8217;re referring to. And if you are using the name in the context of a class, the members of the class have priority over names outside the class.<\/p>\n<p>In other words, the method names <code>Style<\/code> and <code>Visibility<\/code> cause the type names to become hidden. (Another name for this is <i>shadowing<\/i>.)<\/p>\n<p>Some people tut-tut at this problem and declared, &#8220;You silly Windows people, using Pascal case for your names. If you had followed the language standard naming pattern, this problem wouldn&#8217;t even exist!&#8221;<\/p>\n<p>The C++ language standard naming convention has the same problem. In the C++ standard library, type names are <code>snake_case<\/code>, and method names are also <code>snake_case<\/code>. The method<\/p>\n<pre>mutex_type* std::shared_lock::<u>mutex<\/u>() const noexcept;\r\n<\/pre>\n<p>has a name <code>mutex<\/code> that shadows the type name <code>std::mutex<\/code>. If you derive from <code>std::shared_lock<\/code> and try to use a <code>mutex<\/code>, you&#8217;re going to get the method, not the type.<\/p>\n<p>Even outside of Windows, type hiding is not a purely theoretical problem: The <code>sys\/stat.h<\/code> header file defines a structure called <code>struct stat<\/code>, as well as a function <code>stat()<\/code>. As a result, you are forced to say <code><u>struct<\/u> stat<\/code> in order to get the structure. Writing <code>stat<\/code> by itself gets you the function.<\/p>\n<p>So keep your eye open for the <code>Color Color<\/code> problem, even if your use case doesn&#8217;t involve <code>Color<\/code>.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Filling in some gaps in the previous discussion.<\/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-102816","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Filling in some gaps in the previous discussion.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102816","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=102816"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102816\/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=102816"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=102816"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=102816"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}