title: Why can't a function in a namespace see my operator<< defined globally?
body: <p>I've defined an <code>operator&lt;&lt;</code> output function for <code>std::pair</code> instances, for use by some unit tests that want to print the values if they don't watch what's expected.  My test code also has pairs that are held as members of another class that has its own <code>operator&lt;&lt;</code> — specifically <code>boost::optional</code>, but for the sake of example I've defined a simple <code>Container</code> class here instead.  The problem is that the <code>operator&lt;&lt;</code> for <code>std::pair</code> values doesn't seem to be visible within the <code>operator&lt;&lt;</code> of the container class.</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;utility&gt;
  
  template &lt;typename T1, typename T2&gt;
  std::ostream &amp;operator&lt;&lt;(std::ostream &amp;out, std::pair&lt;T1, T2&gt; const &amp;pair) {
    return out &lt;&lt; "{ " &lt;&lt; pair.first &lt;&lt; ", " &lt;&lt; pair.second &lt;&lt; " }";
  }
  
  namespace {
  
    template &lt;typename T&gt;
    struct Container {
      T value;
    };
  
    template &lt;typename T&gt;
    std::ostream &amp;operator&lt;&lt;(std::ostream &amp;out, Container&lt;T&gt; const &amp;container) {
      return out &lt;&lt; container.value;  // Error!
    }
  
  }
  
  int main() {
    std::pair&lt;char, int&gt; pair { 'a', 1 };
    Container&lt;std::pair&lt;char, int&gt;&gt; container { pair };
  
    std::cout &lt;&lt; pair &lt;&lt; std::endl;
    std::cout &lt;&lt; container &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>The line near the end that outputs the plain pair works fine.  But when trying to output the pair within the container, the compiler can't find the <code>operator&lt;&lt;</code> for pairs.  Here's the message from GCC:</p>
  
  <pre><code>test.cc: In instantiation of ‘std::ostream&amp; {anonymous}::operator&lt;&lt;(std::ostream&amp;, const {anonymous}::Container&lt;T&gt;&amp;) [with T = std::pair&lt;char, int&gt;; std::ostream = std::basic_ostream&lt;char&gt;]’:
  test.cc:28:16:   required from here
  test.cc:18:16: error: no match for ‘operator&lt;&lt;’ (operand types are ‘std::ostream {aka std::basic_ostream&lt;char&gt;}’ and ‘const std::pair&lt;char, int&gt;’)
       return out &lt;&lt; container.value;
              ~~~~^~~~~~~~~~~~~~~~~~
  </code></pre>
  
  <p>…followed by a long listing of all the candidate <code>operator&lt;&lt;</code> functions that were considered, and why each one isn't suitable (because they're all for different types of values).  My template for <code>std::pair</code> is not in the list.</p>
  
  <p>(This message is from Debian's GCC 6.3.0 with <code>-std=c++14</code>.  I get the same error, with different wording, from Debian's Clang 3.8.1-24 with <code>-std=c++14</code>, and Apple's Clang 1000.11.45.5 (Apple LLVM 10.0.0) with <code>-std=c++17</code>.)</p>
  
  <p>If I remove the anonymous namespace around my <code>Container</code> template and its <code>operator&lt;&lt;</code>, the error goes away.  But that's not really a solution, since in reality the container is <code>boost::optional</code>, which of course is in namespace <code>boost</code>, and I can't change that.</p>
  
  <p>It's not clear to me <em>why</em> my global <code>operator&lt;&lt;</code> isn't visible from within the namespace, since global scope should be part of the search path for unqualified lookup.  My best guess is that it's because my <code>operator&lt;&lt;</code> is a template, and templates don't seem to be part of the initial unqualified lookup, so ADL kicks in and finds a bunch of other <code>operator&lt;&lt;</code> functions defined in <code>std::</code> and as members within <code>std::ostream</code>, so the lookup stops there.  The list of candidate functions (in the compiler's error message) seems to be consistent with that interpretation.  But then it's unclear why it <em>does</em> work when the container is not in a namespace.</p>
  
  <p>Is there a way to make this work without modifying the <code>Container</code> class?</p>
  
  <hr>
  
  <p>(As background: I'm using the Boost.Test library and writing lines like <code>BOOST_TEST(some_func() == boost::make_optional(std::make_pair('a', 1)))</code>, where <code>BOOST_TEST</code> does some macro/template magic to extract the two sides of the expression and output their values if they don't match.  That requires the values to have an <code>operator&lt;&lt;</code> defined.  Boost provides one for <code>optional</code>, and I've written one for the <code>std::pair</code> within it, but the call from the former to the latter is where the problem lies.)</p>