成员通过函数指针调用内联成员函数,是否会内联?

时间:2013-02-05 17:39:34

标签: c++ inline member-function-pointers

我有一组仅运算的函数,它们的调用不是在编译时确定的,而是在运行时确定的。我打算创建一个指向所有这些指针的数组,并通过数组索引处理它们的调用(例如,如果(a> 3)调用第3个)。

这些函数将在循环中大量重复调用,因此必须内联它们以提高性能。

我的问题是,通过内联成员函数指针的这种调用最终会被内联吗?

谢谢!

class foo{
    private:
    int f(int x){return x;}
    int (foo::*pf)(int);
    public:
    foo(){
        pf=&foo::f;
        (*this.*pf)(3); //will this call be inlined?
        f(3);           //this call is surely inlined
    }
};
int main(){
    foo f;
    return 0;
}

4 个答案:

答案 0 :(得分:3)

首先,永远不会保证特定的调用将被内联(缺少使用特定于编译器的扩展),因此代码中的“肯定”并不是一个肯定的赌注。

示例中的函数指针调用可以内联(因为编译器可以使用静态分析来判断正在调用哪个函数)但是这个例子是设计的,我怀疑你的代码就这么简单。

尽管如此,更重要的问题是为什么你现在担心性能?您是否使用您正在尝试改进的探查器确定了实际热点,或者您是否“感觉”这将是一个问题?

专注于编写干净,可理解且可维护的代码,然后然后 编写调试后,您可以专注于性能 - 调整它微观优化。

答案 1 :(得分:1)

如果代码在运行时决定调用哪个函数,显然,函数不能内联 - 除了通过指针调用它之外别无选择。这实际上是“编译器能否弄清楚发生了什么”的情况。在基于某些条件通过指针调用函数的情况下,编译器将需要了解条件如何影响使用哪个指针。如果编译器在编译代码时无法做出决定,那么必须使用函数指针。

因此,在您的示例代码中,编译器可以(如果选择这样做)内联foo和图f

但是,例如,

在构造函数中,例如:

if (x > y) pf = foo::f(); else pf = foo::g();

在其他一些代码中,编译器并不直接了解x& y值正在构建中:

*blah.*pf(); 

无法内联调用,因为编译器不知道fg是否是要调用的函数。

我希望这是有道理的。

[我也想知道为什么你不能使用虚函数...]

答案 2 :(得分:0)

在一般情况下,不,它不会。在您的特定情况下,编译器会看到如何获取指向成员的指针,并且编译器可以看到所有内容,它可以。

答案 3 :(得分:0)

“这些函数将在循环中被大量重复调用,因此必须内联它们以提高性能。”

现在没有这样的事情。

为你的内联ans:  该调用将内联或不依赖于编译器。