EdelSoft
     Home     |     Softwares     |     Documents     |     Links     
Home > Documents > Xerces C++ > Namespace
注意: このページの情報は古くなっています。調べものの参考にはなる可能性がありますが、別途最新の情報を収集してください。
Abstract
バージョン 2.2.0 以降、Xerces C++ は C++ の名前空間機能を利用するようになりました。これにより、コンパイラがサポートしていれば、Xerces C++ の識別子をすべて固有の名前空間の中で扱えるようになっています。
このページでは、Xerces C++ を名前空間つきで利用する方法と、名前空間をまだサポートしていないコンパイラとの互換性を確保するために使われている手段について説明します。
なお、このページにおける「名前空間」は、ANSI 仕様で導入された C++ の機能としての名前空間を指し、XML に関する W3C 勧告である名前空間(Namespaces in XML)を指してはいないことに注意してください。
Using Namespace
Xerces C++ のすべての識別子は、名前空間 xercesc の中で宣言されています(あとで触れるとおり、これは厳密には正しくありません。しかし、このように理解していても通常は問題ありません)。クラス等を使う場合、対応するヘッダファイルをインクルードした上で、スコープ解決演算子 :: を使って次のようにその名前を参照しなければなりません。
#include <xercesc/sax2/DefaultHandler.hpp>

xercesc::DefaultHandler handler;  //xercesc:: を使用
次のようにすると、コンパイルエラーになります。この場合、コンパイラはグローバルな名前空間から識別子 DefaultHandler を探そうとする(しかし、見つからない)ためです。
#include <xercesc/sax2/DefaultHandler.hpp>

DefaultHandler handler;  //コンパイルエラー。DefaultHandler は参照できない
プリフィクス xercesc:: を使わないで特定の識別子を参照できるようにするには、using 宣言を使います。
#include <xercesc/sax2/DefaultHandler.hpp>

using xercesc::DefaultHandler;

DefaultHandler handler;  //OK
using 指令を使うと、特定の名前空間の識別子すべてを参照可能にすることもできます。適切な利用はクライアントコードを見やすくするといえますが、乱用すると名前空間を使用している意味がありません。面倒がらずに参照したいすべての識別子を using 宣言したほうがいいでしょう。
#include <xercesc/sax2/DefaultHandler.hpp>

using namespace xercesc;

DefaultHandler handler;  //OK
Namespace Macros
自分のコンパイラは名前空間をサポートしているはずなのに、先ほどのコード例で xercesc 名前空間を参照するとコンパイルエラーになり、エラーになるはずの 2 番目のコード例だけがうまくいく、という場合は、Xerces C++ が名前空間を使用する設定になっていません。
Xerces C++ は名前空間を使いますが、世の中にはまだこの機能をサポートしていない C++ コンパイラもあります。そのようなコンパイラで使う場合にも問題を引き起こさないよう、Xerces C++ は名前空間を使わないで(つまり、すべての識別子をグローバルな名前空間において)利用することもできるようになっているのです。これには、C 言語以来の伝統あるプリプロセッサ マクロが使われています。
通常 C++ では、特定の名前空間を作るために namespace XXXX { で始まり } で終わるブロックを使いますが、このようにすると名前空間をサポートしないコンパイラに対応できません。Xerces C++ では代わりに、XERCES_CPP_NAMESPACE_BEGIN マクロと XERCES_CPP_NAMESPACE_END マクロでブロックが作られています。
XERCES_CPP_NAMESPACE_BEGIN

    //
    //クラスや何やらの宣言または定義...
    //

XERCES_CPP_NAMESPACE_END
この 2 つのマクロはそれぞれ、名前空間をサポートしたコンパイラでは namespace XERCES_CPP_NAMESPACE { と } とに、サポートしないコンパイラでは空の文字列に展開されます。
namespace XERCES_CPP_NAMESPACE {  //マクロ展開後 -- 名前空間をサポートする場合

    //
    //クラスや何やらの宣言または定義...
    //

}
これらのマクロは xercesc/util/XercesDefs.hpp で定義されていますが、名前空間サポート用に定義されるか、それとも空の定義を与えられるかを決めるのは、XERCES_HAS_CPP_NAMESPACE という別のマクロです。XERCES_HAS_CPP_NAMESPACE マクロが定義されている場合に、先述のマクロが名前空間をサポートするように定義されます。
XERCES_HAS_CPP_NAMESPACE マクロを定義するかしないかは、プログラマが決定することができます。自分の使うコンパイラが名前空間をサポートしていれば、このマクロを定義するようにします。名前空間がサポートされていないか、何らかの理由で名前空間を使いたくない場合には、このマクロが定義されないようにします。この変更は、xercesc/util/Compilers/ にあるヘッダを修正することで行えます。このディレクトリにあるヘッダファイルのいずれかが、コンパイラがデフォルトで定義する識別用のマクロ(にしたがって AutoSense.hpp で定義されるマクロ)にしたがって、XercesDefs.hpp にインクルードされます。どのヘッダを修正したらよいかは、ファイル名から容易に想像がつくでしょう。たとえば Borland C++ の場合、BorlandCDefs.hpp です。
なお、名前空間サポートを変更した場合には、Xerces C++ のライブラリをビルドしなおすこともお忘れなく。
Real Identifier & Alias
このページの冒頭で、Xerces C++ の名前空間は xercesc であると説明しました。しかし XERCES_CPP_NAMESPACE_BEGIN マクロは、実際には別のマクロ XERCES_CPP_NAMESPACE を使って定義されています。このマクロは xerces/util/XercesVersion.hpp で定義されていて、xercesc_x_x のようにメジャーバージョン、マイナーバージョンが明記された識別子として展開されます。Xerces C++ の各バージョンの識別子は、実際には次のように、それぞれ固有の名前空間の中にあることになります。
namespace xercesc_2_3 {  //マクロ展開後 -- Xerces C++ 2.3.0 の場合

    //
    //クラスや何やらの宣言または定義...
    //

}
一方 xercesc は何かといえば、これは XercesDefs.hpp で作られている、マクロ XERCES_CPP_NAMESPACE の(すなわち本当の名前空間名 xerces_x_x の)エイリアスです。このエイリアスを使えば、どのバージョンの Xerces C++ の名前空間とも互換性が確保できることになります。
よって、クライアントコードから Xerces C++ の名前空間識別子を参照する場合、次のような指針を取ればよいことになります。まず、クライアントコードをそのコードが書かれた際に使われたのと正確に一致するバージョンの Xerces C++ に依存させたい場合には、xercesc_2_3::DefaultHandler のようにバージョンを明示します。また、クライアントコードに常に最新の Xerces C++ を利用させたい場合には、xercesc::DefaultHandler のように名前空間のエイリアスを使います。最後に、自分の書いたクライアントコードがどこか別の場所で使われる場合で、そこで利用されるコンパイラが名前空間をサポートしているという確証が得られないときは、XERCES_CPP_NAMESPACE_QUALIFIER DefaultHandler のように再びマクロを利用します。このマクロは、名前空間をサポートしている状態では xercesc:: に、そうでない状態では空の文字列に展開されるようになっており、名前空間をサポートしないコンパイラとの間でコードの互換性を担保します。以下はそれぞれの例です。
#include <xercesc/sax2/DefaultHandler.hpp>

//Xerces C++ 2.3.0 を使用
xercesc_2_3::DefaultHandler handler;

//おそらく最新の Xerces C++ を使用
xercesc::DefaultHandler handler;

//名前空間をサポートしないコンパイラに互換性のあるコード
XERCES_CPP_NAMESPACE_QUALIFIER DefaultHandler handler;
通常は、エイリアス xercesc:: を使っていれば問題ないはずです。このサイトのほかのページでも、特別な必要のない場合は解説やコード例で xercesc:: を使うものとします。
なお、Xerces C++ の提供する名前空間関係のマクロで、紹介しなかった最後のひとつに XERCES_CPP_NAMESPACE_USE マクロがあります。名前から推測できると思いますが、その意味については調べてみてください。
Resources
Home > Documents > Xerces C++ > Namespace