是否仍然建议将仿函数传递给STL而不是函数?

Vor*_*rac 7 c++ stl

在Effective STL中,Scott Meyers在2001年提出建议:

第46项:考虑函数对象而不是函数作为算法参数

在上面的章节中,他继续解释inline operator()可以内联到算法的主体,但通过函数通常不能.这是因为我们实际上传递了一个函数指针.

为了支持这一点,我似乎记得,如果一个函数的地址被采用,该函数不能内联.

所以这里有两个问题.首先,C++ 14仍然如此吗?

如是:

  • 为什么没有自动执行此操作的机制(动机:声明一个仿函数比声明一个函数要简单易懂和可读).
  • 没有捕获的lambda可以转换为函数指针,而捕获lambda只能作为仿函数传递.这是否意味着我们只需要为了所述的优化而捕获某些东西?

T.C*_*.C. 7

这对C++ 14来说仍然如此吗?

取决于编译器是否可以内联整个算法.如果可以,那么它也可以内联函数调用.如果没有,那么函数可能无法内联,因为在这种情况下的算法是使用函数指针类型实例化的,因此必须能够处理该类型的所有函数指针.

例如,g ++可以内联一个简单的算法,std::transform但不是std::sort.

没有捕获的lambda可以转换为函数指针,而捕获lambda只能作为仿函数传递.这是否意味着我们只需要为了在顶级优化中说明而捕获某些内容?

没有.没有捕获的lambda仍然是一个算符; 使用闭包类型(lambda的类型)而不是函数指针类型来实例化算法.


Seb*_*edl 5

为了支持这一点,我似乎记得,如果一个函数的地址被采用,该函数不能内联.

你读错了.如果编译器可以跟踪函数指针,则可以将函数内联到任何直接调用站点和任何间接调用站点.GCC联机帮助页所说的是,内联到每个调用站点的函数根本不会作为单独的函数发出(因此减少二进制大小),除非采用其地址.

首先,C++ 14仍然如此吗?

是.当然,现在你通常会写lambda而不是手工编写的仿函数.

为什么没有机制自动执行此操作.

这是类型系统的问题.具有给定签名的所有函数具有相同的类型.因此,传递函数指针的算法被实例化为一个具体函数,并且其代码在C++的编译模型中只存在一次.

当然,优化器仍然可以在一个特定参数上专门化该函数,但这是一个比仅仅内联函数更高级的优化.所以,是的,有一种机制,它不太可能被使用.

这是否意味着我们只需要为了在顶级优化中说明而捕获某些内容?

第一个函数指针的转换是可能的,但除非你调用它明确的,它不会被当你通过一个lambda的算法来完成.