<html>
<style>
ins {background-color:#FFFFA0}
del {background-color:#FFFFA0}
</style>
<body>
<h1>Namespace Association ("strong" using)</h1>
Jason Merrill
<br>2007-06-22
<br>Document Number N2331=07-0191
<br>Revision 1

<h2>Introduction</h2>

This paper provides proposed wording for the extension referred to
in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2013.html">
N2013</a> as "namespace association".

<h2>The Problem</h2>

In <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1344.pdf">
N1344</a>, Herb Sutter discussed the problems of shared library versioning
specifically with regard to allowing the C++98 and C++0x standard libraries
to coexist, going over various options and the problems with them.

<p>On page 7, he writes "One might think that a more C++-ish way of hoisting a
facility into two namespaces would be to use
a <code>using-declaration</code>. One would be almost right."

<p>It does seem that <code>using</code> would be a good way to separate the
actual implementation from the namespace that we want other code to
interact with.  But as Herb notes, the problem with this is that we can
only specialize a template in its actual namespace, not a namespace it has
been imported into.  Also, argument-dependent lookup breaks down if library
components are split across multiple namespaces.

<h2>The Proposed Solution</h2>

The proposed extension creates a stronger <code>using-directive</code> that
allows other code to define and specialize members of the used namespace as
though they actually belong to the using namespace.  This is referred to as
namespace association because of its effects on argument-dependent lookup.

<p>This paper proposes adding the <code>extern</code> keyword to
the <code>using-directive</code> to request the additional behavior, but
other syntax choices would be possible.

<p>For instance:

<pre>
namespace Lib
{
  namespace Lib_1 { }
  extern using namespace Lib_1;

  namespace Lib_1
  {
    template <typename T> class A; 
  }

  template <typename T> void g(T);
}
...
struct MyClass { ... };
namespace Lib
{
  template<> class A<MyClass> { ... };
}

int main()
{
  Lib::A<MyClass> a;
  g(a);  // ok, Lib is an associated namespace of A
}
</pre>

<h2>Proposed Wording</h2>

<h3>In [namespace.udir] and appendix A</h3>
Change the grammar for using-directive to

<blockquote><pre>
<i>using-directive:</i>
        extern<sub>opt</sub> using  namespace ::<sub>opt</sub> <i>nested-name-specifier<sub>opt</sub> namespace-name ;
</i></pre></blockquote>

<h3>Also in [namespace.udir]</h3>
Add a new paragraph:

<p>If the <tt>extern</tt> specifier is used, the used namespace must be a
  member (possibly indirect) of the current namespace.  Such a
  using-directive declares the using namespace to be an associated
  namespace ([basic.lookup.argdep]) of the used namespace.  Furthermore,
  members of the used namespace can subsequently be defined
  ([namespace.memdef]), explicitly instantiated ([temp.explicit]) or
  explicitly specialized ([temp.expl.spec]) as though they were a member of
  the using namespace.

<h3>In [basic.lookup.argdep]</h3>
Add to the end of paragraph 2:

<p>If any of the associated namespaces have their own associated namespaces
  ([namespace.udir]), those are also included in the set.

<h3>In [namespace.memdef]</h3>
Add a new paragraph:

<p><b>-4-</b> If a named namespace has associated namespaces
  ([namespace.udir]), its members can also be defined within an associated
  namespace, or by explicit qualification with an associated namespace.

<h3>In [temp.explicit]</h3>

<p><b>-5-</b> An explicit instantiation of a class or function template
  specialization is placed in the namespace in which the template is
  defined<b>, or an associated namespace thereof</b>.  An explicit
  instantiation for a member of a class template is placed in the namespace
  where the enclosing class template is defined<b>, or an associated
  namespace thereof</b>.  An explicit instantiation for a member template
  is placed in the namespace where the enclosing class or class template is
  defined<b>, or an associated namespace thereof</b>.


<h3>In [temp.expl.spec]</h3>

<p><b>-2-</b> An explicit specialization shall be declared in the namespace
  of which the template is a member, or, for member templates, in the
  namespace of which the enclosing class or enclosing class template is a
  member<b>, or an associated namespace thereof</b>.  An explicit
  specialization of a member function, member class or static data member
  of a class template shall be declared in the namespace of which the class
  template is a member<b>, or an associated namespace thereof</b>.  Such a
  declaration may also be a definition.  If the declaration is not a
  definition, the specialization may be defined later in the namespace in
  which the explicit specialization was declared, or in a namespace that
  encloses the one in which the explicit specialization was declared.

<h2>References</h2>

Benjamin Kosnik, 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2013.html">
Versioning with Namespaces</a>, N2013

<p>Herb Sutter,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1344.pdf">
Namespaces and Library Versioning</a>, N1344

</body>
</html>
