boost::lambda と LNK2005 "シンボル沢山定義されてるよ" エラー

プリコンパイル済みヘッダーで #include して次のコードをビルドしたのですよ。


size_t CMailCheckResult::GetTotalReceiveMailCount()
{
    return std::accumulate(m_stlFieldList.begin(), m_stlFieldList.end(), static_cast<size_t>(0),
        boost::lambda::_1 + boost::lambda::bind(&SMailCheckResultField::m_nReceiveMailCount, boost::lambda::_2));
}

そしたら


リンクしています...
kanaria.obj : error LNK2005: "class lambda_functor >::boost::lambda_functor > const & const boost::lambda::`anonymous namespace'::_1" (?_1@?A0xb4088928@lambda@boost@@3ABV?$lambda_functor@U?$placeholder@$00@lambda@boost@@@23@B) は既に stdafx.obj で定義されています。
kanaria.obj : error LNK2005: "class lambda_functor >::boost::lambda_functor > const & const boost::lambda::`anonymous namespace'::_2" (?_2@?A0xb4088928@lambda@boost@@3ABV?$lambda_functor@U?$placeholder@$01@lambda@boost@@@23@B) は既に stdafx.obj で定義されています。
kanaria.obj : warning LNK4006: "class lambda_functor >::boost::lambda_functor > const & const boost::lambda::`anonymous namespace'::_1" (?_1@?A0xb4088928@lambda@boost@@3ABV?$lambda_functor@U?$placeholder@$00@lambda@boost@@@23@B) は stdafx.obj で定義されています。2 つ目以降の定義は無視されます。
kanaria.obj : warning LNK4006: "class lambda_functor >::boost::lambda_functor > const & const boost::lambda::`anonymous namespace'::_2" (?_2@?A0xb4088928@lambda@boost@@3ABV?$lambda_functor@U?$placeholder@$01@lambda@boost@@@23@B) は stdafx.obj で定義されています。2 つ目以降の定義は無視されます。
   ライブラリ Debug/rmbiff.lib とオブジェクト Debug/rmbiff.exp を作成中
Debug/rmbiff.rzmd : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。

なんていわれてしまった。う〜ん?

_1, _2 とかは、boost::lambda のヘッダーで定義されてはいるものの、const なオブジェクトですから複数回定義されてても問題ないはずだし…う〜ん。原因がわからん。


時間もないし、いろいろ実験するのもメンドイので(ぉ、結局次のようにして解決しちゃいました。

size_t CMailCheckResult::GetTotalReceiveMailCount()
{
    const boost::lambda::placeholder1_type _1;
    const boost::lambda::placeholder2_type _2;

    return std::accumulate(m_stlFieldList.begin(), m_stlFieldList.end(), static_cast<size_t>(0),
        _1 + boost::lambda::bind(&SMailCheckResultField::m_nReceiveMailCount, _2));
}

ローカルの変数を見に行けば問題ないじゃろー。多分。 ^^;

確か、重要なのは _1 の placeholder1_type 等の "型" が重要だったはずなので、コレで問題無い…ハズ。 で、この記憶が確かであれば、ぶっちゃけ

size_t CMailCheckResult::GetTotalReceiveMailCount()
{
    const boost::lambda::placeholder1_type kana;
    const boost::lambda::placeholder2_type hina;

    return std::accumulate(m_stlFieldList.begin(), m_stlFieldList.end(), static_cast<size_t>(0),
        kana + boost::lambda::bind(&SMailCheckResultField::m_nReceiveMailCount, hina));
}

とかいうコードが書けるはず。 思わずウッハー!と喜んでしまうわけですが、そんなのは私だけですかそうですかそうですか。*1

*1:まぁ、やらんけど^^;