<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<style type="text/css">
.comment { color: #999999; font-style: italic; }
.pre { color: #000099; }
.string { color: #009900; }
.char { color: #009900; }
.float { color: #996600; }
.int { color: #999900; }
.bool { color: #000000; font-weight: bold; }
.type { color: #FF6633; }
.flow { color: #FF0000; }
.keyword { color: #990000; }
.operator { color: #663300; font-weight: bold; }
.operator { color: #663300; font-weight: bold; }
pre.code {
    border: 2px solid #666;
    background-color: #F4F4F4;
    padding-left: 10px;
    padding-top: 0px;
}
code {
    border: 2px solid #d0d0d0;
    background-color: LightYellow;
    padding: 2px;
    padding-left: 10px;
    display:table;
    white-space:pre;
    margin:2px;
    margin-bottom:10px;
}
dt
{
    font-weight: bold;
}
    
.ins {
    background-color:#A0FFA0;
}

.del {
    background-color:#FFA0A0;
    text-decoration:line-through
}    
</style><title>Specialization and namespaces</title>
<body>
<p>N3730<br/>
    2013-08-28<br/>
    Mike Spertus<br/>
    <a href="mailto:mike_spertus@symantec.com"><tt>mike_spertus@symantec.com</tt></a><br/></p>

<h1>Specializations and namespaces</h1>
<h2><a name="Overview"></a>Overview</h2>
<p>We propose to allow specializing templates from within a different namespace. 
 The
motivation is that when we declare a new class, it is natural to want to provide associated
template specializations. For example, it is really painful that whenever I declare a class,
I need to class all open namespaces and enter namespace <tt>std</tt> just to specialize
<tt>std::hash</tt> as shown below
<code>namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { 
      <span class="comment">/* ... */</span> 
    };  
  }
}

namespace std {
  template&lt;&gt;
  struct hash&lt;A::B::C&gt; {
    size_t operator()(A::B::C const &amp;c) { <span class="comment">/* ... */</span> }
  };
}

namespace A { <span class="comment">/* Reenter namespace I am using */</span>
  namespace B { 
      <span class="comment">/* ... */</span>
  }
}
</code></p>
<p>Instead, I should be able to specialize <tt>std::hash&lt;C&gt;</tt> contiguous with the
rest of the definition of <tt>class C</tt> without having to break out of
its namespace:
<code>namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { 
      <span class="comment">/* ... */</span> 
    };
      
    template&lt;&gt;
    struct ::std::hash&lt;C&gt; {
      std::size_t operator()(C const &amp;c) { <span class="comment">/* ... */</span> }
    };
    <span class="comment">/* ... */</span>
  }
}</code>The technical point is that the primary template identifies
the template's namespace, so we don't need to use the namespace enclosing the specialization's definition
to identify it's namespace.
</p>
<p>We also propose (to be straw-polled separately) the use of <tt>friend</tt> to put
specializations of external templates in a class, just like we allow external friend
functions to be defined within a class:
<code>namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { 
      <span class="comment">/* ... */</span>
      template&lt;&gt;
      friend struct ::std::hash&lt;C&gt; {
        std::size_t operator()(C const &amp;c) { <span class="comment">/* ... */</span> }
      };
    };
  }
}</code></p>
<p>We also discuss an alternative approach of allowing namespaces to be open in a non-containing
namespace.</p>
<h2>Motivation</h2>
<p>The primary motivation is that the natural place to specialize templates for a class
is often alongside the definition of the class.</p><ul> <li>In the <a href="#Overview">Overview</a>, we
illustrate this for <tt>std::hash</tt>.</li> <li><tt>std::less</tt> provides another example of this.</li>
<li>In in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3403.pdf">n3403</a>, it is
anticipated that the (not yet existent) <tt>std::prompt</tt> will often be explicitly specialized.</li>
<li>Of course, this doesn't just apply for template classes in <tt>std</tt>. The same considerations
apply to specializing <tt>boost::fusion::traits::tag_of</tt> in the 
<a href="http://www.boost.org/doc/libs/1_35_0/libs/fusion/doc/html/fusion/extension/ext_full.html#fusion.extension.ext_full.enabling_tag_dispatching">Enabling Tag Dispatching example</a>
in the Boost.Fusion documentation.</li> <li>Specializing test classes in a putative test framework could also benefit 
from something like this.</li> <li>Creating explicit specializations of current or future type traits that yet lack compiler intrinsics.</li>
<li>As one other example that some (but not all) may find interesting, I have worked on a multi-million line code base that
had a <tt>DEFINE_CLASS</tt> preprocessor macro to define classes according the the local coding standards. One of the things this macro
did was to specialize an <tt>XXX::Guid</tt> struct for this class, so that each conforming class had a GUID. In part due to the need 
to exit and reenter the namespace in this macro, the entire codebase was placed in a single namespace (Yes, all of the namespace
info could be put in the macro, but avoiding such boilerplate is a primary motivation for the macro in the first place)</li>   
<li>and so forth</li></ul>

<h2>Specializing in a different namespace</h2>
<p>The rules for specializing in a different namespace are fairly straightforward.</p>
<h3>The primary template is identified using normal lookup rules</h3>
<p>For example, all of the following are OK. For clarity, the varying 
sections are <span style="color:green">green</span>.
<code>namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { 
      <span class="comment">/* ... */</span> 
    };
      
    template&lt;&gt;
    struct <span style="color:green">::std::hash</span>&lt;C&gt; {
      std::size_t operator()(C const &amp;c) { <span class="comment">/* ... */</span> }
    };
    <span class="comment">/* ... */</span>
  }
}</code>
<code>namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { 
      <span class="comment">/* ... */</span> 
    };
      
    template&lt;&gt;
    struct <span style="color:green">std::hash</span>&lt;C&gt; {
      std::size_t operator()(C const &amp;c) { <span class="comment">/* ... */</span> }
    };
    <span class="comment">/* ... */</span>
  }
}</code> 
<code><span style="color:green">using namespace std;</span>
namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { 
      <span class="comment">/* ... */</span> 
    };
      
    template&lt;&gt;
    struct <span style="color:green">hash</span>&lt;C&gt; {
      std::size_t operator()(C const &amp;c) { <span class="comment">/* ... */</span> }
    };
    <span class="comment">/* ... */</span>
  }
}</code></p>
<p>The same rule applies to declarations
<code>using namespace std;
namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { 
      <span class="comment">/* ... */</span> 
    };
      
    template&lt;&gt;
    struct hash&lt;C&gt;;
    <span class="comment">/* ... */</span>
  }
}</code></p>
<h3>The current lexical scope is used</h3>
<p>I propose using the current lexical scope both because it seems more natural to me,
and is more compatible with the rules for defining <tt>friend</tt> members in &sect;11.3p7.
This consistency is particularly nice when we discuss declaring <tt>friend</tt> specializations
<a href="#friend">below</a>.
<code>namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { 
      <span class="comment">/* ... */</span> 
    };
      
    template&lt;&gt;
    struct std::hash&lt;C&gt; { <span class="comment">// OK</span>
      std::size_t operator()(C const &amp;c) { <span class="comment">/* ... */</span> }
    };
    struct less&lt;A::B::C&gt; { <span class="comment">// Error: Not in namespace <tt>std</tt>. Also too awkward.</span>
      bool operator()(C const &amp;c) { <span class="comment">/* ... */</span> }
    };
    <span class="comment">/* ... */</span>
  }
}</code></p>
<h3>All explicit specializations are supported</h3>
<p>While the illustrations above have all been fully specializing classes, there is no
restriction on the type of specialization.
<code>template&lt;class C, int i = 0&gt;
struct Foo {
	std::string foo() { return "foo" };
};
template&lt;class C&gt;
struct Bar {
	std::string bar() { return "bar" };
}
namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { 
      <span class="comment">/* ... */</span> 
    };
      
    template&lt;int i&gt;
    struct Foo&lt;C, i&gt; { <span class="comment">// OK. Partial specialization</span>
      <span class="comment">/* ... */</span> 
    };
    template&lt;&gt;
    std::string Bar&lt;C&gt;::bar()) { <span class="comment">// OK. ordinary method specialization</span>
      return "Special bar"; 
    };
    <span class="comment">/* ... */</span>
  }
}</code></p>
<h2><a name="friend"></a><tt>friend</tt> specializations</h2>
<p>Just as we allow external functions to be defined as friends (&sect;11.3p6), we 
allow specializations to be defined as friends. There is one important difference,
which is that the specialization is naturally placed in the namespace of the primary template,
not in namespace scope (as for function definitions in &sect;11.3p6).
<code>namespace A { <span class="comment">// Repeated from Overview for easy reference</span>
  namespace B {
    <span class="comment">/* ... */</span>
    class C { 
      <span class="comment">/* ... */</span>
      template&lt;&gt;
      friend struct hash&lt;C&gt; { <span class="comment">// Specializes <tt>std::hash</tt></span>
        std::size_t operator()(C const &amp;c) { <span class="comment">/* ... */</span> }
      };
    };
  }
}</code></p>
<p>Note that this only allows specializations to be defined as friends. Support for declaring
classes or primary templates is not required. (However, speaking personally, allowing declarations
of friend classes seems worthwhile in conjunction with
ADL for template parameters, but this is not required for this proposal...)

<h2>Additional functionality: Opening namespaces in non-containing namespaces</h2>
<p>This section looks at allowing a namespace to be opened while in a non-containing namespace
<code>namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { <span class="comment">/* ... */</span> };
    
    namespace ::std {  
      template&lt;&gt;
      struct hash&lt;A::B::C&gt; {
        size_t operator()(A::B::C const &amp;c) { <span class="comment">/* ... */</span> }
      };
      <span class="comment">/* ... */</span>
    }
  }
}</code></p>
<p>This has the benefit of being more general than just allowing specialization in another namespace.
For example, if we want to create a header that can be <tt>#include</tt>ed from within while within a namespace
(e.g., to use multiple versions of the same API within a single program),
we can write
<code><span class="comment">// Foo.h</span>
namespace :: { <span class="comment">// Make sure we are in global scope</span>
#include &lt;string&gt;
}
<span class="comment">/* ... */</span></code></p>
<p>While this is nice, I am not recommending adding this functionality for the following reasons:</p>
<ul><li>It does not handle the primary motivating example of specializing
as well as the approaches above.  In particular, this approach doesn't
encapsulate the definitions of the specializations with the definition of
the class nearly as well.</li>
<li>By operating in the lexical scope of the namespace containing the primary template, 
it is awkward to define the specialization as illustrated by the need to repeatedly
use <tt>A::B::C</tt> in the first example in this section.</li>
<li> To reopen
global scope, you need to say "<tt>namespace :: {</tt>" as "<tt>namespace {</tt> already has
a special meaning, potentially leading to errors:<code><span class="comment">// Foo.h</span>
namespace { <span class="comment">// Oops! Including &lt;string&gt; in unnamed namespace</span>
#include &lt;string&gt;
}
<span class="comment">/* ... */</span></code>
 </li>
<li>Even if you are opening a non-global scope, the use of "<tt>::</tt>" is mandatory,
which is also error-prone:
<code>namespace A {
  namespace B {
    <span class="comment">/* ... */</span>
    class C { <span class="comment">/* ... */</span> };
    
    namespace std { <span class="comment">// Oops! Trying to specialize in A::B::std</span>  
      template&lt;&gt;
      struct hash&lt;A::B::C&gt; {
        size_t operator()(A::B::C const &amp;c) { <span class="comment">/* ... */</span> }
      };
      <span class="comment">/* ... */</span>
    }
  }
}</code><li>Perhaps the inclusions from within a namespace use case could eventually
be better handled by modules.</li> </ul>

</body>
</html>
