1

以下のコードのネストされたが、主要なコンパイラ (VS2010/2012、gcc、clang) によってstd::bind暗黙的に に変換されないのはなぜですか? std::function<void()>これは標準的な動作ですか、それともバグですか?

#include <functional>

void bar(int, std::function<void()>) { }
void foo() { }

int main()
{
    std::function<void(int, std::function<void()>)> func;
    func = std::bind(bar, 5, std::bind(foo));

    std::cin.get();
    return 0;
}
4

1 に答える 1

4

これはブーストのドキュメントで説明されています:

内部バインド式は、関数オブジェクトが呼び出されたときに外部バインドの前に不特定の順序で評価されます。評価の結果は、外側のバインドが評価されるときに代わりに代入されます。上記の例では、関数オブジェクトが引数リスト (x) で呼び出されると、bind(g, _1)(x) が最初に評価され、g(x) が生成され、次に bind(f, g(x))( x) が評価され、最終結果 f(g(x)) が得られます。

Boost はprotect、この評価を防ぐためにも提供します。

#include <boost/bind/protect.hpp>
...
func = std::bind(bar, 5, boost::protect(std::bind(foo)));

ただし、呼び出すfuncには、次のように両方の引数を提供する必要があるため (David Rodríguez に感謝します- それを指摘してくれたdribeasに感謝します)、この例は明らかに良くありません:

func(1, std::function<void()>());
于 2012-11-28T23:01:57.440 に答える