意外に使いにくい C++ の新ライブラリ

最近では、TR1 や C++0x(C++1x といったほうが正確か?)にある程度対応した処理系も増えてきました。ところが、対応状況が中途半端な上に、処理系ごとにいろいろとローカルルールがあるので御しにくいのも事実です。移植性のことを考えなければ問題ないのかもしれませんが、移植性を気にしだすと、Visual C++ と GCC に限っても、結構めんどうです。

対象とするのを、Visual C++ 2008(2010 はまだベータなので考慮しません)と GCC 3.4 以上(Cygwin とか考慮すると、どうしてもそうなります)に絞ったとします。その場合でも、インクルードすべきヘッダの違い、名前空間の違いがあり、それらを自動判別してやらなければなりません。

Visual C++ の場合、一部しか対応していないとはいえ、基本的に TR1 の仕様通りの使い方ができます。すなわち、tuple を使いたいのであれば、<tuple> をインクルードし、std::tr1 名前空間にあるものとして扱えばよいことになります。

GCC の場合、TR1 に対応するのはバージョン 4 以上ですので、__GNUC__ マクロで判別する必要があります。C++0x のライブラリも途中のバージョンから断片的にサポートされ始めますが、-std=c++0x または -std=gnu++0x オプションを指定する必要があるため、デフォルトでは使うことができません。TR1 ライブラリを使う場合、<tr1/tuple> のように、ヘッダ名が tr1/* のようになってしまいます。

また、GCC バージョン 3 の場合は TR1 もサポートされませんので、Boost C++ Libraries の TR1 ライブラリに依存することになるでしょう。その場合のヘッダ名は、<boost/tr1/tuple.hpp> となります。名前空間は std::tr1 が使えます。

このように、TR1 ライブラリを使うことを基本とすれば、名前空間に関しては std::tr1 に統一できそうです。もちろん、将来的には std 名前空間になるわけですから、現時点でもそうしておきたいという欲求はあります。

namespace std { using namespace tr1; }

のようにして、std 名前空間にすることは可能ですが、やや(いろいろな意味で)気持ち悪いのも確かです。この辺りは好みの問題かもしれません。

ヘッダ名の互換性のなさはかなり深刻です。マクロを使ってヘッダ名を合成させるのもよいのですが、やはり気持ち悪さは残ります。かといって、その都度 #if 指令で仕分けるのも不細工です。変則的なヘッダ名が必要になるのは GCC の場合だけなので、ダミーのヘッダファイルを作って、そこからインクルードさせる方法は悪くありませんが、それなりに手間です。

こんな感じで、現時点では意外に使いにくかったりします。大した問題ではないといえばそうなのかもしれませんが、少なくとも手軽さはありません。

この記事のトラックバックURL:

http://www.kijineko.co.jp/trackback/626
このエントリーを含むはてなブックマーク