web-dev-qa-db-ja.com

いつstd :: bindを使用すればよいですか?

std::bindを使用する必要があるたびに、代わりにラムダを使用することになります。では、いつstd::bindを使用すればよいですか? 1つのコードベースから削除したところ、ラムダはstd::bindよりも常にシンプルで明確であることがわかりました。 std::bindは完全に不要ではありませんか?将来的に非推奨にすべきではないでしょうか?ラムダ関数よりstd::bindのほうがいいのはいつですか? (ラムダと同時に標準に入った理由があるはずです。)

また、ラムダに慣れている人が増えていることにも気づきました(ラムダの働きを知っているからです)。ただし、std::bindおよびstd::placeholdersに精通している人ははるかに少ない。

37
gnzlbg

これはラムダではできないことです:

std::unique_ptr<SomeType> ptr = ...;
return std::bind(&SomeType::Function, std::move(ptr), _1, _2);

ラムダは移動のみのタイプをキャプチャできません。コピーまたは左辺値参照によってのみ値をキャプチャできます。確かに、これはC++ 14で積極的に解決されている一時的な問題です;)

「よりシンプルで明確」は意見の問題です。単純なバインディングの場合、bindを使用すると、入力を大幅に減らすことができます。 bindも関数バインディングにのみ焦点を当てているため、std::bind、あなたはあなたが何を見ているか知っています。一方、ラムダを使用する場合は、ラムダの実装を調べて、その動作を確認する必要があります。

最後に、C++は、他のいくつかの機能がその機能を実行できるという理由だけで、物事を非難しません。 auto_ptr本質的に危険であり、危険ではない代替手段があるため、廃止されました。

30
Nicol Bolas

std::bindを使用してポリモーフィックオブジェクトを作成できますが、ラムダを使用して作成することはできません。つまり、std::bindによって返される呼び出しラッパーは、さまざまな引数タイプで呼び出すことができます。

#include <functional>
#include <string>
#include <iostream>

struct Polly
{
  template<typename T, typename U>
    auto operator()(T t, U u) const -> decltype(t + u)
    { return t + u; }
};

int main()
{
  auto polly = std::bind(Polly(), std::placeholders::_1, "confusing");

  std::cout << polly(4) << polly(std::string(" this is ")) << std::endl;    
}

私はこれを puzzle として作成しましたが、良いコードの例ではありませんが、ポリモーフィックな呼び出しラッパーを示しています。

23
Jonathan Wakely