title: Using std::array and using "array" as name
body: <p>In my C++ JSON library, I recently had a <a href="https://github.com/nlohmann/json/issues/590" rel="noreferrer">regression with GCC7</a>. I stripped down the affected code and hope to understand the error.</p>
  
  <h1>The code</h1>
  
  <p>Consider this header <code>myclass.hpp</code>:</p>
  
  <pre><code>#pragma once
  
  template &lt;typename X&gt;
  struct A
  {
      struct value_t
      {
          X array;
      };
  
      static A array()
      {
          return A();
      }
  
      friend bool operator&lt;(const A&amp; lhs, const A&amp; rhs) noexcept
      {
          return lhs.val.array &lt; rhs.val.array;
      }
  
      value_t val = {};  
  };
  </code></pre>
  
  <p>As you see, I used the name "array" as member variable name in struct <code>value_t</code>, as name of a static function. I then included the header in the following file:</p>
  
  <pre><code>#include &lt;array&gt;
  using std::array; // note this!
  #include "myclass.hpp"
  
  int main()
  {}
  </code></pre>
  
  <h1>The problem</h1>
  
  <p>The code compiles with GCC6 and Clang5 (using <code>-std=c++11</code>), but GCC7 reports:</p>
  
  <pre><code>In file included from example.cpp:3:0:
  myclass.hpp: In function 'bool operator&lt;(const A&lt;X&gt;&amp;, const A&lt;X&gt;&amp;)':
  myclass.hpp:19:40: error: wrong number of template arguments (1, should be 2)
           return lhs.val.array &lt; rhs.val.array;
                                          ^~~~~
  In file included from example.cpp:1:0:
  /usr/local/Cellar/gcc/7.1.0/include/c++/7.1.0/array:94:12: note: provided for 'template&lt;class _Tp, long unsigned int _Nm&gt; struct std::array'
       struct array
              ^~~~~
  make: *** [all] Error 1
  </code></pre>
  
  <p>It seems as if the parser reads the "array" in <code>lhs.val.array</code> as <code>std::array</code> and treats the following <code>&lt;</code> as the start of a template list.</p>
  
  <p>The code can be compiled if I make any of the changes below:</p>
  
  <ul>
  <li>Remove the <code>using std::array;</code> or move it behind <code>#include "myclass.hpp"</code>.</li>
  <li>Change <code>return lhs.val.array &lt; rhs.val.array;</code> to <code>return (lhs.val.array) &lt; rhs.val.array;</code>.</li>
  </ul>
  
  <p>In addition, either compiler fails if I remove the <code>static A array()</code> function...</p>
  
  <h1>My questions</h1>
  
  <ul>
  <li>Is the code correct in the first place? Am I allowed to use "array" as a name even if I use <code>using std::array;</code>?</li>
  <li>If the code is correct, is this a bug in GCC7?</li>
  </ul>