It may seem tidy to add your new declarations to the ``++std++`` or ``++posix++`` namespaces, but doing so results in undefined behavior. The {cpp}14 Standard, [namespace.std] (ISO/IEC 14882-2014 §17.6.4.2.1), paragraphs 1 and 2 states:


____

. The behavior of a {cpp} program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
. The behavior of a {cpp} program is undefined if it declares:
** an explicit specialization of any member function of a standard library class template, or
** an explicit specialization of any member function template of a standard library class or class template, or
** an explicit or partial specialization of any member class template of a standard library class or class template.
____

In addition to restricting extensions to the ``++std++`` namespace, the {cpp}14 Standard goes on in §17.6.4.2.2 to say:

____

. The behavior of a {cpp} program is undefined if it adds declarations or definitions to namespace posix or to a namespace within namespace posix unless otherwise specified. The namespace posix is reserved for use by ISO/IEC 9945 and other POSIX standards.
____

You may think that it's legitimate to reopen ``++std++`` to define a version of extension points (``++std::swap++``, ``++std::hash++``...) that work with your types, but it's not necessary:  If you call these extension points according to the correct pattern (see for instance S5963 for ``++swap++``), user-defined version will be found too.


This rule raises an issue for any modification of the standard ``++std++`` and ``++posix++`` namespaces.


== Noncompliant Code Example

----
namespace MyNamespace {
  class MyType {/*...*/};
}
namespace std { // Noncompliant
  int x;
  void swap(MyNamespace::MyType &m1, MyNamespace::MyType &m2);
}
----


== Compliant Solution

----
namespace expanded_std {
  int x;
}
namespace MyNamespace {
  class MyType {/*...*/};
  void swap(MyType &m1, MyType &m2); // See also S5963 to see how to properly call it
}
----


== Exceptions

A namespace fragment that only contains template specializations or explicit instantiations is ignored by this rule.


== See

* https://wiki.sei.cmu.edu/confluence/x/Xnw-BQ[CERT, DCL58-CPP.] - Do not modify the standard namespaces


ifdef::env-github,rspecator-view[]
'''
== Comments And Links
(visible only on this page)

include::comments-and-links.adoc[]
endif::env-github,rspecator-view[]
