为啥 std::bind 不能作为参数包的参数?
Posted
技术标签:
【中文标题】为啥 std::bind 不能作为参数包的参数?【英文标题】:Why std::bind can't be param of parameters pack?为什么 std::bind 不能作为参数包的参数? 【发布时间】:2013-11-19 02:55:37 【问题描述】:我想使用参数包,但发现问题。 一些代码:
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);
应用程序不再编译。
那么,在pack中使用函数作为参数有什么问题呢?
谢谢。
更新: 如果将 f 的代码更改为:
template <typename Function, typename... Args>
auto f(Function func, Args... args) -> decltype(func(args...))
func(args...);
效果很好,但我不想在这里执行这个函数,我想创建函数并像参数一样传递它。
更新 2: 代码执行示例:http://ideone.com/gDjnPq
更新3: 清除编译错误代码:http://ideone.com/50z7IN
【问题讨论】:
然后添加最重要的部分。尝试破译它并阅读它想说的内容。如果没有错误,没有人可以帮助您。 你能把sscce.org放在ideone之类的东西上并添加一个链接,以便我们可以看到生成的错误消息吗? 如果不是auto
,你可以让它工作,给printFunction
输入std::function<void(const char*)>
。我不知道这是为什么。来自 clang 的错误消息表明它无法推断出 _Result
类型的绑定表达式。
这里是上面的一个 sscce:ideone.com/50z7IN -- 我还不知道为什么它不能编译,但它就是!
Answer is here一些具体的std::bind。
【参考方案1】:
我现在对情况有了一些了解。
此代码可以追溯问题:
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)))();
而且效果很好。
【讨论】:
以上是关于为啥 std::bind 不能作为参数包的参数?的主要内容,如果未能解决你的问题,请参考以下文章
第11课 std::bind和std::function_std::bind绑定器
C++11 std::bind std::function 变参函数