1

std::bind の戻り値の型は (意図的に) 指定されていません。std::function に格納できます。

以下のサンプル プログラムは、fn1() を呼び出すために、std::bind() によって返された一時オブジェクトを std::function に明示的にキャストする方法を示しています。

std::bind の戻り値の型がわかっている場合、Callback コンストラクターをオーバーロードでき、std::bind 一時オブジェクトを明示的にキャストする必要がなくなります。

明示的なキャストを回避する方法はありますか?

// g++ -std=c++11 test.cxx
#include <functional>

using std::placeholders::_1;

class A
{
    public:
        void funcA (int x) { }
};

class Callback
{
    public:
        Callback () = default;
        Callback (std::function<void(int)> f) { }
        // Wish we knew the return type of std::bind()
        // Callback (return_type_of_std_bind f) { }
};

void fn0 (std::function<void(int)> f) { }
void fn1 (Callback cb) { }

int main (void)
{
    A a;
    fn0(std::bind(&A::funcA, &a, _1)); // ok
    fn1(std::function<void(int)>(std::bind(&A::funcA, &a, _1))); // ok, but verbose
    fn1(std::bind(&A::funcA, &a, _1)); // concise, but won't compile
}

おそらく関係ありませんが、Linux で gcc 4.7.2 を使用しています。

4

1 に答える 1

11

Callbackユニバーサルコンストラクターを与えるのが最善です:

struct Callback
{
    typedef std::function<void(int)> ftype;
    ftype fn_;

    template <typename T,
              typename = typename std::enable_if<std::is_constructible<ftype, T>::value>::type>
    Callback(T && f) : fn_(std::forward<T>(f))
    { }
};

(2 番目の既定のテンプレート引数を追加しTて、ステートメントが意味を持つ型に対してのみこのコンストラクターを有効にし、誤った変換可能性プロパティを作成しないようにしました。)の明示的なコンストラクターを呼び出しfn_ます。

于 2013-01-15T23:15:23.823 に答える