title: boost::program_options appears to cast std::array to boost::array
body: <p>Consider the following program:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;sstream&gt;
  #include &lt;array&gt;
  #include &lt;type_traits&gt;
  
  #ifdef DO_BOOST_PO_TEST
  #include &lt;boost/program_options.hpp&gt;
  namespace po = boost::program_options;
  #endif
  
  template &lt;size_t I, typename T, size_t N&gt;
  typename std::enable_if&lt;(I==N-1)&gt;::type
  array_elem_from_istream(std::istream&amp; in, std::array&lt;T,N&gt;&amp; arr) {
    std::stringstream ss;
    in.get(*ss.rdbuf(),(char)EOF);
    ss &gt;&gt; std::get&lt;I&gt;(arr);
  }
  
  template &lt;size_t I, typename T, size_t N&gt;
  typename std::enable_if&lt;(I&lt;N-1)&gt;::type
  array_elem_from_istream(std::istream&amp; in, std::array&lt;T,N&gt;&amp; arr) {
    std::stringstream ss;
    in.get(*ss.rdbuf(),':');
    ss &gt;&gt; std::get&lt;I&gt;(arr);
    in.ignore(); // skip delim char
    array_elem_from_istream&lt;I+1&gt;(in,arr);
  }
  
  namespace std {
    template &lt;typename T, size_t N&gt;
    istream&amp; operator&gt;&gt;(istream&amp; in, array&lt;T,N&gt;&amp; arr) {
      array_elem_from_istream&lt;0&gt;(in,arr);
      return in;
    }
  }
  
  int main(int argc, char *argv[])
  {
    std::array&lt;double,3&gt; arr;
  
    #ifndef DO_BOOST_PO_TEST
    std::stringstream(argv[1]) &gt;&gt; arr;
    #else
  
    try {
      po::options_description desc("Options");
      desc.add_options()
        ("arr,a", po::value(&amp;arr), "array test");
      po::positional_options_description pos;
      pos.add("arr",1);
  
      po::variables_map vm;
      po::store(po::command_line_parser(argc, argv)
        .options(desc).positional(pos).run(), vm);
      po::notify(vm);
    } catch (std::exception&amp; e) {
      std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
      return 1;
    }
    #endif
  
    for (auto x : arr) std::cout &lt;&lt; x &lt;&lt; std::endl;
  
    return 0;
  }
  </code></pre>
  
  <p>If compiled with</p>
  
  <pre><code>g++ -std=c++11 -Wall test.cc -o test
  </code></pre>
  
  <p><code>./test '1:5:9'</code> prints</p>
  
  <pre><code>1
  5
  9
  </code></pre>
  
  <p>as expected. But compiling with</p>
  
  <pre><code>g++ -std=c++11 -Wall -DDO_BOOST_PO_TEST test.cc -o test -lboost_program_options
  </code></pre>
  
  <p>results in an error. The most enlightening part of the error message is</p>
  
  <pre><code>/foo/bar/include/boost/lexical_cast/detail/converter_lexical_streams.hpp:601:32: error: no match for ‘operator&gt;&gt;’ (operand types are ‘std::basic_istream&lt;char&gt;’ and ‘boost::array&lt;double, 3ul&gt;’)
  </code></pre>
  
  <p>Why in the world is it looking for <code>operator&gt;&gt;(std::istream&amp;, boost::array&lt;double, 3ul&gt;&amp;)</code> when it should be using <code>operator&gt;&gt;(std::istream&amp;, std::array&lt;double, 3ul&gt;&amp;)</code>?</p>
  
  <p>If I change my <code>array_elem_from_istream</code> and <code>istream&amp; operator&gt;&gt;</code> template functions' <code>arr</code> arguments to <code>boost:array</code>, but keep the <code>std::array&lt;double,3&gt; arr;</code> in the <code>main</code> as is, it works!</p>
  
  <p>Why is <code>std::array&lt;double,3&gt;</code> being casted to <code>boost::array&lt;double,3&gt;</code> by <code>boost::program_options</code>? This is the first time I've seen <code>boost::program_options</code> change the type for which it looks for the stream operator.</p>