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...);
}

它工作得很好,但我不想在这里执行这个函数,我想创建函数并像参数一样传递它。

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 回答