如果我有一个没有状态的仿函数类,但是我使用 new 从堆中创建它,那么典型的编译器是否足够聪明,可以完全优化创建开销?
这个问题是在制作一堆无状态函子时出现的。如果它们被分配在堆栈上,它们的 0 状态类主体是否意味着堆栈真的根本没有改变?看来它必须以防您稍后获取仿函数实例的地址。堆分配也一样。
在这种情况下,仿函数总是在它们的创建中增加一个(微不足道的,但非零的)开销。但也许编译器可以看到该地址是否被使用,如果没有,它可以消除堆栈分配。(或者,它甚至可以消除堆分配吗?)
但是作为临时创建的函子怎么样?
#include <iostream>
struct GTfunctor
{
inline bool operator()(int a, int b) {return a>b; }
};
int main()
{
GTfunctor* f= new GTfunctor;
GTfunctor g;
std::cout<< (*f)(2,1) << std::endl;
std::cout<< g(2,1) << std::endl;
std::cout<< GTfunctor()(2,1) << std::endl;
delete f;
}
所以在上面的具体例子中,三行分别以三种不同的方式调用同一个函子。在此示例中,这些方式之间是否存在效率差异?或者编译器是否能够一直优化每一行,直到成为一个无计算的打印语句?
编辑:大多数答案说编译器永远不能内联/消除堆分配的仿函数。但这也是真的吗?大多数编译器(GCC、MS、Intel)也有链接时间优化,它们确实可以进行这种优化。(但有吗?)