8

キーを持つ単純な構造体を格納するマップがあります。構造体には 2 つのメンバー関数があり、1 つは const で、もう 1 つはそうではありません。std::for_each を使用して const 関数を問題なく呼び出すことができましたが、非 const 関数の呼び出しに問題がありました。

struct MyStruct {
  void someConstFunction() const;
  void someFunction();
};

typedef std::map<int, MyStruct> MyMap;
MyMap theMap;

//call the const member function
std::for_each(theMap.begin(), theMap.end(),
   boost::bind(&MyStruct::someConstFunction, boost::bind(&MyMap::value_type::second, _1)));

//call the non-const member function
std::for_each(theMap.begin(), theMap.end(),
   boost::bind(&MyStruct::someFunction, boost::bind(&MyMap::value_type::second, _1)));

const メンバー関数の呼び出しは正常に機能しますが、boost は内部的に const MyStruct を予期しているように見えるため、MSVC7.1 では次のコンパイル エラーで失敗します。

boost\bind\mem_fn_template.hpp(151): エラー C2440: '引数': 'const MyStruct *__w64 ' から 'MyStruct *const ' に変換できません

テンプレートパラメーターを正しく設定する方法について何か助けていただければ幸いです。バインドはパラメーターを正しく認識し、非 const 関数を呼び出すことができます。

ありがとう、カール

4

4 に答える 4

8

IIRC、Boost.Bind はboost::mem_fnメンバー機能へのバインディングに使用します。ここで、mem_funを見ると(その部分までスクロールし// data member supportます)、result_type を const& として型定義していることがわかりますが、非 const メンバーから非 const メンバーの抽出をサポートする関数呼び出し演算子のオーバーロードがまだあります。 -const 引数。

したがって、問題は、これが Boost.Bind の戻り型推論メカニズムを混乱させることであると思われます。したがって、解決策は、結果が const ではないことを Bind に明示的に伝えることです。

//call the non-const member function
std::for_each(theMap.begin(), theMap.end(),
   boost::bind(&MyStruct::someFunction, 
       boost::bind<MyStruct&>(&MyMap::value_type::second, _1)
   )
);
于 2010-02-22T16:19:06.633 に答える
7

これを頻繁に行う必要がある場合は、Boost.RangeExライブラリを使用することをお勧めします。

#include <boost/range/algorithm/for_each.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/mem_fn.hpp>
#include <map>

struct MyStruct {
  void someConstFunction() const;
  void someFunction();
};

typedef std::map<int, MyStruct> MyMap;
MyMap theMap;

int main()
{
    //call the const member function
    boost::for_each(theMap | boost::adaptors::map_values,
                    boost::mem_fn(&MyStruct::someConstFunction));

    //call the non-const member function
    boost::for_each(theMap | boost::adaptors::map_values,
                    boost::mem_fn(&MyStruct::someFunction));
}

Boostに受け入れられましたが、まだ正式なディストリビューションには含まれていません。それが完了する まで、Boost Vaultからダウンロードできます(zipファイルへのダウンロードリンク)。

于 2010-02-22T15:45:33.457 に答える
4

すでに に依存している場合は、 Boost ForeachBoostをチェックしてみてください。

BOOST_FOREACH(MyMap::value_type const& val, MyMap)
{
  val.second.someConstFunction();
}

パフォーマンスの問題についてはわかりませんが、非常に読みやすいです。

,また、文字を「エスケープ」せずにマクロ内で型指定されたテンプレートを使用できないことに注意してください。

  • 前にtypedefによって
  • または、型の周りに 2 番目の括弧のペアを使用して
于 2010-02-22T15:35:28.907 に答える
0

私が見つけた 1 つの問題: 2 番目のバインドは、非関数メンバーに対して呼び出されます。2 番目はデータ メンバーであり、std::pair のメソッドではありません

于 2010-02-22T15:18:18.947 に答える