c++ - 使用 std::function 或转发引用作为高阶函数的通用可调用对象输入参数?

标签 c++ c++11 std-function perfect-forwarding

我想知道编写一个以 std::function 作为输入参数的高阶函数的主要区别、优缺点。或转发引用,例如template<typename F> void hof(F&& fun); . 显然,前者比后者更严格,因为它指定了输入可调用对象必须符合的函数类型

最佳答案

std::function 通常具有显着的运行时开销。通过 template 参数传递通用可调用对象可避免 std::function 的间接成本,并允许编译器积极优化

我在 the end of this article 为 lambda 递归编写了一些简单的基准测试 (Y 组合器与 std::function) . std::function 生成的程序集总是比非多态 Y 组合器实现多至少 3.5 倍。这是一个不错的示例,它展示了std::function 如何比template 参数更昂贵。

我建议在 gcc.godbolt.org 上玩玩查看两种技术之间的装配差异。


这是一个例子 I just came up with :

#if defined(STDFN)
void pass_by_stdfn(std::function<void()> f)
{
    f();
}
#else
template <typename TF>
void pass_by_template(TF&& f)
{
    f();
}
#endif

volatile int state = 0;

int main()
{
#if defined(STDFN)
   pass_by_stdfn([i = 10]{ state = i; });
#else
   pass_by_template([i = 10]{ state = i; });  
#endif
}

使用STDFN 未定义,生成的程序集是:

main:
        mov     DWORD PTR state[rip], 10
        xor     eax, eax
        ret
state:
        .zero   4

使用 STDFN 定义,生成的程序集有 48 行长。

关于c++ - 使用 std::function 或转发引用作为高阶函数的通用可调用对象输入参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40973130/

相关文章:

c++ - C++ 中的通用工厂

c++ - cout set_precision(5) + fixed 和 printf 之间的区别 ("%lf.5",var)

c++ - 一个互斥锁与多个互斥锁。线程池用哪个好?

c++ - 可变参数模板函数确定函数指针返回类型

c++ - 为什么我们不能简单地复制 std::function

c++ - 使用 std::function 作为参数的可变参数模板

c++ - 在 vector c++ 中保存大数据

c++ - 错误 : passing 'const string' as this argument of push_back

c++ - 异步运行的函数的返回类型应该是什么

C++ shared_ptr std::bind 和 std::function