title: std::make_pair type deduction
body: <p>I came across some odd thing I would like to have an explanation for. The following code snippet provides a simple class template <code>type</code> and two <code>operator&lt;&lt;</code>s: one for specializations of <code>type</code> and one for a <code>std::pair</code> of <code>type</code> specializations.</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;ostream&gt;
  #include &lt;utility&gt;
  
  template &lt;typename T&gt;
  class type {
  
  public:
  
    T value_;
  
  };
  
  template &lt;typename CTy, typename CTr, typename T&gt;
  std::basic_ostream&lt;CTy,CTr&gt;&amp;
  operator&lt;&lt;(std::basic_ostream&lt;CTy,CTr&gt;&amp; os, type&lt;T&gt; const&amp; a)
  {
    return os &lt;&lt; a.value_;
  }
  
  template &lt;typename CTy, typename CTr, typename T&gt;
  std::basic_ostream&lt;CTy,CTr&gt;&amp;
  operator&lt;&lt;(std::basic_ostream&lt;CTy,CTr&gt;&amp; os, std::pair&lt;T const, T const&gt; const&amp; a)
  {
    return os &lt;&lt; a.first &lt;&lt; ',' &lt;&lt; a.second;
  }
  
  #include &lt;iostream&gt;
  
  int
  main()
  {
    using float_type = type&lt;float&gt;;
  
    float_type const a = { 3.14159 };
    float_type const b = { 2.71828 };
  
  #if 0
    std::cout &lt;&lt; std::make_pair(a, b)
              &lt;&lt; std::endl;
  #else
    std::cout &lt;&lt; std::pair&lt;float_type const, float_type const&gt;(a, b)
              &lt;&lt; std::endl;
  #endif
  }
  </code></pre>
  
  <p>The <code>main</code> function provides a specialization and two variables of that specialization. There are two variants for displaying the variables as a <code>std::pair</code>. The first fails because <code>std::make_pair</code> seems to strip the <code>const</code> specifier from the variables, which in turn doesn't match with the signature of the second <code>operator&lt;&lt;</code>: <code>std::pair&lt;T const, T const&gt;</code>. However, constructing a <code>std::pair</code> specialization (second <code>std::cout</code> line in <code>main</code>) works as well as removing the <code>const</code> specification for <code>T</code> from <code>operator&lt;&lt;</code> for <code>std::pair</code>, i.e. <code>std::pair&lt;T, T&gt;</code>.</p>
  
  <p>Compiler messages::</p>
  
  <ul>
  <li><p>gcc 4.9.2</p>
  
  <pre><code>std_make_pair.cpp: In function 'int main()':
  std_make_pair.cpp:52:35: error: cannot bind 'std::ostream {aka std::basic_ostream&lt;char&gt;}' lvalue to 'std::basic_ostream&lt;char&gt;&amp;&amp;'
     std::cout &lt;&lt; std::make_pair(a, b) &lt;&lt; std::endl;
                                 ^
  In file included from std_make_pair.cpp:3:0:
  /usr/include/c++/4.9.2/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream&lt;_CharT, _Traits&gt;&amp; std::operator&lt;&lt;(std::basic_ostream&lt;_CharT, _Traits&gt;&amp;&amp;, const _Tp&amp;) [with _CharT = char; _Traits = std::char_traits&lt;char&gt;; _Tp = std::pair&lt;type&lt;float&gt;, type&lt;float&gt; &gt;]'
   operator&lt;&lt;(basic_ostream&lt;_CharT, _Traits&gt;&amp;&amp; __os, const _Tp&amp; __x)
   ^
  </code></pre></li>
  <li><p>clang 3.5 (non-viable functions from system headers removed)</p>
  
  <pre><code>std_make_pair.cpp:52:13: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream&lt;char&gt;')
    and 'pair&lt;typename __decay_and_strip&lt;const type&lt;float&gt; &amp;&gt;::__type, typename __decay_and_strip&lt;const
    type&lt;float&gt; &amp;&gt;::__type&gt;')
    std::cout &lt;&lt; std::make_pair(a, b) &lt;&lt; std::endl;
    ~~~~~~~~~ ^  ~~~~~~~~~~~~~~~~~~~~
  
  std_make_pair.cpp:30:1: note: candidate template ignored: can't deduce a type for 'T' which would make
    'const T' equal 'type&lt;float&gt;'
  operator&lt;&lt;(std::basic_ostream&lt;CTy,CTr&gt;&amp; os, std::pair&lt;T const, T const&gt; const&amp; a)
  </code></pre></li>
  </ul>
  
  <p>so, here's the question: am I supposed to specify an <code>operator&lt;&lt;</code> taking a <code>std::pair</code> of <code>T</code> instead of <code>T const</code>? Isn't that watering down the contract I'm setting up with any user of the functionality, i.e. with <code>T const</code> I basically promise to use <code>T</code> only in non-mutating ways?</p>