3

パラメータパックを使いたいのですが、問題が見つかりました。いくつかのコード:

template <typename Function, typename... Args>
auto f(Function func, Args... args) -> decltype(func(args...))
{
    auto f11 = std::bind(func, args...);
    f11();
}

void print(const char* string)
{
    std::cout << string << std::endl;
}

これはすべてうまくいきます:

    f([] (const char* additional, const char* more) {
        std::cout << "hello ( " << additional << ", " << more << " )" << std::endl;
    }, "additional text", "and one more");

    auto printFunction = std::bind(&print, std::placeholders::_1);

    printFunction("hello from print bind");

    f(print, "hello from print directly");

しかし、std::function をパラメーター パックに渡したい場合:

f([] (std::function<void(const char*)> printParamFunc) {
 printParamFunc("hello from print from std::function");
}, printFunction);

アプリケーションはコンパイルされなくなります。

では、パックのパラメータとして関数を使用する問題は何ですか?

ありがとう。

更新: f のコードを次のように変更した場合:

template <typename Function, typename... Args>
auto f(Function func, Args... args) -> decltype(func(args...))
{
    func(args...);
}

うまく機能しますが、ここでこの関数を実行したくありません。関数を作成して、param のように渡したいのです。

UPDATE2: コード実行例: http://ideone.com/gDjnPq

UPDATE3: コンパイル エラーでコードをクリア: http://ideone.com/50z7IN

4

1 に答える 1

0

状況が少しよくわかりました。

この問題は、次のコードで再現できます。

void print(const char* string)
{
    std::cout << string << std::endl;
}

int main(int argc, char ** argv)
{
    auto lambda = [] (std::function< void ( const char * ) > printParamFunc) {
        printParamFunc("hello from lambda!");
    };

    std::bind(lambda, std::bind(print, std::placeholders::_1))();
}

ネストされた std::bind が評価を試み、_1 から const char * への変換で失敗します。これは std::bind に固有のものです。

boost::bind::protect -- 他のファンクターを格納するファンクター -- の類似物が必要であり、問​​題を解決します:

template <class F>
struct lazy_evaluate {
    typedef typename F::result_type T;

    explicit lazy_evaluate(F f) : f_(f) {}

    template <class... Args>
    T operator()(Args&&... args) 
    {
        f_(std::forward<Args>(args)...);
    }

private:
    F f_; 
};

template <class F>
lazy_evaluate<F> lazy(F f)
{
    return lazy_evaluate<F>(f);
}

ネストされた std::bind は次のようになります。

std::bind(lambda, lazy(std::bind(print, std::placeholders::_1)))();

そしてうまくいきます。

于 2013-11-08T11:19:33.903 に答える