<html>
<style>
ins {background-color:#FFFFA0}
del {background-color:#FFFFA0}
</style>
<body>
<h1>Namespace Association ("inline namespace")</h1>
Jason Merrill
<br>2008-02-27
<br>Document Number N2535=08-0045
<br>Revision 8

<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".

The syntax in this revision of the paper has changed significantly from
previous revisions.

<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 allows the use of the <code>inline</code> keyword in
a <code>namespace-definition</code> to specify that members of the
namespace can be defined and specialized as though they actually belong to
the enclosing namespace.  This is referred to as namespace association
because of its effects on argument-dependent lookup.

<p>This extension has been implemented in the GNU and EDG compilers for
several years now (expressed with a special using-directive, rather than a
change to the namespace definition itself), and is getting a fair amount of
use.

<p>The syntax in this proposal has changed based on suggestions from other
members of the committee, notably Daveed Vandevoorde.

<p>For instance:

<pre>
namespace Lib
{
  inline namespace Lib_1
  {
    template &lt;typename T&gt; class A; 
  }

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

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

<h2>Proposed Wording</h2>

<h3>In [namespace.def]</h3>
Change the grammar as follows:

<blockquote><pre>
<i>original-namespace-definition:</i>
	<b>inline<sub>opt</sub></b> namespace <i>identifier</i> { <i>namespace-body</i> }
<i>extension-namespace-definition:</i>
	<b>inline<sub>opt</sub></b> namespace <i>original-namespace-name</i> { <i>namespace-body</i> }
<i>unnamed-namespace-definition:</i>
	<b>inline<sub>opt</sub></b> namespace { <i>namespace-body</i> }
</blockquote>

Also add new paragraphs:

<b><p>If the optional initial <tt>inline</tt> keyword appears in
a <i>namespace-definition</i> for a particular namespace, that namespace is
declared to be an <i>inline namespace</i>.  The <tt>inline</tt> keyword may
be used on an <i>extension-namespace-definition</i> only if it was
previously used on the <i>original-namespace-definition</i> for that
namespace.

<p>Members of an inline namespace can be used in most respects as though they
were members of the enclosing namespace.

Specifically, the inline namespace and its enclosing namespace are
considered to be associated namespaces ([basic.lookup.argdep]) of one
another, and a using directive ([namespace.udir]) which names the inline
namespace is implicitly inserted into the enclosing namespace.

Furthermore, each member of the inline namespace can subsequently be
explicitly instantiated ([temp.explicit]) or explicitly specialized
([temp.expl.spec]) as though it were a member of the enclosing namespace.
Finally, looking up a name in the enclosing namespace via explicit
qualification ([namespace.qual]) will include members of the inline
namespace brought in by the using directive even if there are declarations
of that name in the enclosing namespace.

<p>These properties are transitive: if a namespace N contains an inline
namespace M, which in turn contains an inline namespace O, then the members
of O can be used as though they were members of M or N.  The set of
namespaces consisting of the innermost non-inline namespace enclosing an
inline namespace O, together with any intervening inline namespaces, is
the <i>enclosing namespace set</i> of O.</b>

<h3>In [basic.lookup.argdep]</h3>
Add after the bulleted list in paragraph 2:

<p><b>If an associated namespace is an inline namespace ([namespace.def]),
  its enclosing namespace is also included in the set.  If an associated
  namespace contains inline namespaces, those inline namespaces are also
  included in the set.</b> In addition, if the argument is the name or
  address of a set of overloaded functions and/or function templates...

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

In paragraph 2:

<p>An explicit instantiation shall appear in an enclosing namespace of its
  template. If the name declared in the explicit instantiation is an
  unqualified name, the explicit instantiation shall appear in the
  namespace where its template is declared<b> or, if that namespace is
  inline ([namespace.def]), any namespace from its enclosing namespace
  set.</b>

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

<p><b>-2-</b> An explicit specialization shall be declared in
  the <b>nearest enclosing namespace of the template</b> <s>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</s><b>, or, if that namespace is inline ([namespace.def]), any
  namespace from its enclosing namespace set</b>.  <s>An explicit
  specialization of a member template, 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.</s>  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.

<h3>In [dcl.meaning] paragraph 1</h3>

<p>When the <i>declarator-id</i> is qualified, the declaration shall refer
  to a previously declared member of the class or namespace to which the
  qualifier refers <b>(or of an inline namespace within that scope
  [namespace.def])</b>, and the member shall not have been introduced by a
  <i>using-declaration</i> in the scope of the class or namespace nominated by the
  <i>nested-name-specifier</i> of the <i>declarator-id</i>.

<h3>In [namespace.qual] paragraph 2</h3>

  Given X::m (where X is a user-declared namespace), or given ::m (where X
  is the global namespace), let S be the set of all declarations of m in X
  and in the transitive closure of all namespaces nominated by
  using-directives in X and its used namespaces, except that
  using-directives <b>that nominate non-inline namespaces
  ([namespace.def])</b> are ignored in any namespace, including X, directly
  containing one or more declarations of m. No namespace is searched more
  than once in the lookup of a name. If S is the empty set, the program is
  ill-formed. Otherwise, if S has exactly one member, or if the context of
  the reference is a using-declaration (7.3.3), S is the required set of
  declarations of m. Otherwise if the use of m is not one that allows a
  unique declaration to be chosen from S, the program is ill-formed.

<h3>In [reserved.names]</h3>

Insert a new paragraph 2:

<p><b>A program shall not declare namespace <tt>std</tt> to be an inline
namespace ([namespace.def]).</b>

<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>
