std名前空間にテンプレートの特殊化を追加する

多くのC++プログラマは「std名前空間には何物も追加してはならない」という認識で一致していると思うのですが,実はこれには例外が存在します.以下,標準から抜粋.

17.4.3.1 Reserved names
1 It is undefined for a C++ program to add declarations or definitions to namespace std or namespaces within namespace std unless otherwise specified. A program may add template specializations for any standard library template to namespace std. Such a specialization (complete or partial) of a standard library template results in undefined behavior unless the declaration depends on a user-defined name of external linkage and unless the specialization meets the standard library requirements for the original template.
17.4.3.1 予約された名前
1 C++プログラムがstd名前空間もしくはその内側の名前空間に宣言や定義を追加することは,他で特に指定がない限り未定義である.プログラムはあらゆる標準ライブラリのテンプレートに対する特殊化をstd名前空間に加えることが出来る.そのような標準ライブラリのあるテンプレートに対する(完全または部分)特殊化は,その宣言が外部リンケージを持つユーザ定義の名前に依存していて,かつその特殊化が元のテンプレートに対する要求を満たしていなければならず,それ以外では未定義の動作を引き起こす.

従って,以下のようなプログラムは書いて構わないことになります.

class my_container // ユーザが定義したコンテナクラス
{
.....
};

#include <algorithm> // 特殊化の宣言の前にオリジナルのテンプレート
                     //(プライマリテンプレートと呼ばれる)の宣言を導入しておく

namespace std{

template<>
void swap<my_container>(my_container &x, my_container &y)
{
  // my_containerに対するstd::swapの特殊化
.....
}

}

class my_int // ユーザが定義した整数クラス
{
.....
};

#include <limits> // 同様にプライマリテンプレートの宣言をあらかじめ導入しておく

namespace std{

struct numeric_limits<my_int>
{
  // my_intに対するnumeric_limitsの特殊化
.....
};

}