bind と lambda と _1さん の相性問題

昨日のビルドできない問題ですが、結論としては boost::lambda::_1 と bind の _1 が被ってるとみなされることによる問題のようでした。つまり、VCのコンパイラ(プリコンパイル済みヘッダーを作る段階?)が悪いような気がします。それぞれの _1 は、違う名前空間に居るわけですから。

……とはいえ、個人的には boost 側がおかしいような気がしないでもないのです。いやまぁ、ライブラリ作られている方は、私よりよっぽど C++ に精通している事確実なので、何か深い理由があるのかもしれませんが…少なからず私には疑問が残る点がいくつかあったり。

ヘッダに書く "変数"

bind の _1 等 は、(VCの場合)次の様にヘッダに書かれています。

// placeholders.hpp(42)
static boost::arg<1> _1;
static boost::arg<2> _2;
static boost::arg<3> _3;
static boost::arg<4> _4;
  :
  :

まず、この点でおかしい気がするわけです。 なんで const修飾子が無いんだろう と。

const を付けた「定数(コンパイル時定数?)」であれば、ヘッダーに書いても多重定義とみなされずOKだったりします。

ところが、「変数」をヘッダー書いて、いろんな cpp から #include してしまうと、その変数のインスタンスが大量に出来てしまい「沢山定義されてます」コンパイルエラーが出てしまうハズなんですよ。

…いやまぁ、通常であれば実際はそんなエラー出ないので、C++の規格的に何か例外っぽいものがあるのかもしれませんが……。ウチ的には、なんで「定数じゃなくて変数なんだろう?」という疑問が一点。

名前空間

bind は boost 名前空間で定義されていますが、bind の _1 次のようにヘッダーに書かれています。

namespace
{
  :
static boost::arg<1> _1;
static boost::arg<2> _2;
static boost::arg<3> _3;
static boost::arg<4> _4;
  :
  :

} // unnamed namespace

…なんで boost名前空間に入れていないんだろう

名前空間の最後に「unnamed namespace」なんてコメントが入っている以上、明らかに意思的に 無名名前空間 で定義している事がわかります。 …が、何でだろう…。

つか、ヘッダーで無名名前空間を利用するって何か利点あるんでしょうか…^^;
実質グローバルと扱いが変わらない気がするんですが……。

問題解決方法

結局 bind の _1等を boost 名前空間で定義されるように

namespace boost
{
  :
static boost::arg<1> _1;
static boost::arg<2> _2;
static boost::arg<3> _3;
static boost::arg<4> _4;
  :
  :

} // <del>unnamed</del> boost namespace

という感じにしたところ、ようやく何事も無かったかのようにビルドが通ってくれました。(なんで const が無くてもOKなのか良くわかりません^^;)

が、正直既存のライブラリにテコ入れして利用するって、なんか悔しいよね。(何

VC も変。

bind の _1 が lambda の _1被るとはいえ、定義されている場所は

_1;                 // bind の _1 は(実質)グローバル
boost::lambda::_1;  // lambda の _1 は lambda名前空間で定義されている

という具合に違ってるわけで、本当は何も被らないと思うワケですよ。 lambda の _1 を lambda::bind に投げるにしても、boost::lambda::_1 として修飾してあげないといけないですし。(…いやまぁ、なんかそれ以前に問題があるような気もしますけど)
VC側も、名前の解決法方法(プリコンパイル済みヘッダー作成時の何か?)がおかしいような気もします。




ただ、個人的には bind の _1 が boost 名前空間に入ってない方がおかしいような気がしてなりません。^^;

でも、私が利用し始めた boost 1.30 ぐらいからこんな仕様だった気もするので、やっぱり何か意思的な何かがあるんだろうなぁ…。う〜ん。なんなんだろう。







…あぁでも、それ以前に重大な問題があることに気づきました。




なんでマシンによってビルド結果が違ってくるんじゃろ?

やっぱり悪いのは VC 側かしら〜!?