<!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 (Rev. 2)</title>
<body>
<p>N3867<br/>
Revision of N3730<br/>
    2014-01-19<br/>
    Mike Spertus<br/>
    <a href="mailto:mike_spertus@symantec.com"><tt>mike_spertus@symantec.com</tt></a><br/></p>

<h1>Specializations and namespaces (Rev. 2)</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>
<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><a name="tptiiunlr"></a>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> 
<a name="te"></a><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 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>Wording</h2>
<p>
Change &sect;14.7.3p2 [temp.expl.spec] as follows:
<blockquote>An explicit specialization <span class="del">shall be declared in a namespace enclosing the specialized template. An explicit
specialization whose <em>declarator-id</em> is not qualified shall be declared in the nearest enclosing namespace of
the template, or, if the namespace is inline (7.3.1), any namespace from its enclosing namespace set. Such a declaration</span> 
may also be a definition. If the declaration is not a definition, the specialization may be defined
later (7.3.1.2).</blockquote>
<b>Notes:</b>
Can it really be that simple? I will confirm the following items with the appropriate authorities before presenting to EWG.
<ul>
<li>This undoes much of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3064.pdf">N3064</a>,
which allowed specializations to be given in an enclosing namespace to address 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n3006.html#374">core issue 374</a>.
In order to not regress on that issue, I will confirm with the appropriate authorities
whether or not these sentence are safe to delete.</li>
<li>The standard appears to conveniently provide the lexical scope from the discussion above without any wording changes.
</li>
<li>No additional wording changes are necessary for partial specialization.</li>
</ul>
</body>
</html>
