考虑下一个简单的例子:
标题:
// a.hpp
#ifndef A_HPP
#define A_HPP
#include <memory>
class A
{
public:
A();
int foo();
private:
struct Imp;
std::auto_ptr< Imp > pimpl;
};
#endif // A_HPP
实施:
// a.cpp
#include "a.hpp"
struct A::Imp
{
int foo()
{
// do something and return the result
}
};
A::A() : pimpl( new Imp )
{}
int A::foo()
{
return pimpl->foo();
}
主要:
// main.cpp
#include "header.hpp"
int main()
{
A a;
return a.foo();
}
问题是:
方法A::Imp::foo
是否会被内联到A::foo
?
它取决于实现该方法中的内容吗?
PS 我正在使用gcc(4.3.0如果重要的话)。
修改
我想我没解释得很好。我的意思是这个。如果我使用最高优化级别,那么// do something and return the result
是A::foo()
还是A::Imp::foo()
?
如果没有优化,我发现这没有完成(仍然调用the pimpl->foo()
)。
我知道A :: foo()永远不会在main()中内联,但这不是我要问的。
答案 0 :(得分:10)
所有内联都依赖于实现。如果这对您很重要,请查看发出的汇编程序代码。
答案 1 :(得分:8)
Herb Sutter曾做过一篇关于内联的精彩文章。
要问的第一个问题是:何时可以内联?
在C ++中:
两次,机制都类似:如果编译器/链接器知道该方法的实现,它可能决定复制/粘贴实现而不是发出调用。这个决定是基于复杂的启发式方法,我只知道它们存在,而不是它们的存在。
因此关键点是知道实现位。
所以在这里:是的,可以在pimpl->foo()
内内联呼叫A::foo
。它将取决于编译器和编译选项。
对于gcc / clang,如果A::Impl::foo
足够小,可以从O1开始优化(除非你通过-fno-inline
)。