web-dev-qa-db-ja.com

C ++ 11 std :: bindとboost :: bindの違い

2つの間に違いはありますか?または、コード内のすべてのboost::bindstd::bindに置き換えて、Boostへの依存を削除しても安全ですか?

66
Haatschii
  • _boost::bind_ 関係演算子がオーバーロードされています 、_std::bind_はありません。

  • _boost::bind_ デフォルト以外の呼び出し規約をサポート 、_std::bind_は保証されていません(標準ライブラリ実装はこれを拡張機能として提供する場合があります)。

  • _boost::bind_は、ネストされたバインド式の積極的な評価をpreventできるようにする直接的なメカニズムを提供します( _boost::protect_ )、_std::bind_ ではない。 (つまり、必要に応じて_boost::protect_を_std::bind_と組み合わせて使用​​したり、自分で簡単に再実装したりできます。)

  • _std::bind_は、force積極的な評価( _std::is_bind_expression_ :[func.bind.isbind]/1、[func.bind.bind]/10)、_boost::bind_はそうではありません。

86
ildjarn

他の回答で引用されたいくつかの違いに加えて、以下の2つの違いがあります。

  • boost::bindは、状況によってはオーバーロードされた関数名を処理するようですが、std::bindは同じ方法でそれらを扱いません。 c ++ 11 faq を参照してください

(gcc 4.7.2を使用して、libバージョン1_54をブースト)

void foo(){}
void foo(int i){}

auto badstd1 = std::bind(foo);  
//compile error: no matching function for call to bind(<unresolved overloaded function type>)
auto badstd2 = std::bind(foo, 1); 
//compile error: no matching function for call to bind(<unresolved overloaded function type>)
auto std1 = std::bind(static_cast<void(*)()>(foo)); //compiles ok
auto std2 = std::bind(static_cast<void(*)(int)>(foo), 1); //compiles ok
auto boost1 = boost::bind(foo, 1); //compiles ok
auto boost2 = boost::bind(foo); //compiles ok

したがって、単にすべてのboost::bind with std::bind、ビルドが壊れる可能性があります。

  • std::bindはc ++ 11ラムダ型にシームレスにバインドできますが、boost::bind boost 1.54以降、ユーザーからの入力が必要と思われます(return_typeが定義されていない場合)。 boost doc を参照してください

(gcc 4.7.2を使用して、libバージョン1_54をブースト)

auto fun = [](int i) { return i;};
auto stdbound = std::bind(fun, std::placeholders::_1);
stdbound(1);

auto boostboundNaive = boost::bind(fun, _1);  //compile error.
// error: no type named ‘result_type’ ...
auto boostbound1 = boost::bind<int>(fun, _1); //ok
boostbound1(1);
auto boostbound2 = boost::bind(boost::type<int>(), fun, _1); //ok
boostbound2(1);

したがって、単にすべてのstd::bind with boost::bind、ビルドも壊れる可能性があります。

23
orm

上記以外にも、boost :: bindには重要な拡張ポイント:get_pointer()関数があり、boost :: bindをスマートポインターと統合できます。 ATL :: CComPtrなど http://www.boost.org/doc/libs/1_49_0/libs/bind/mem_fn.html#get_pointer

その結果、boost :: bindを使用すると、weak_ptrをバインドすることもできます。 http://lists.boost.org/Archives/boost/2012/01/189529.php

16
Igor R.

完全な答えはありませんが、std::bindはパラメーターリストではなく可変長テンプレートを使用します。

プレースホルダーは、グローバル名前空間ではなく、std::placeholdersと同様にstd::placeholders::_1にあります。

名前空間をstdphにエイリアスします

namespace stdph=std::placeholders;

それとは別に、C++ 11への更新に問題はありませんでした

8
111111