模板中内联函数的好处

时间:2014-05-21 16:50:04

标签: c++ templates inline

根据标准,C ++中成员函数的内联定义与使用inline关键字声明成员函数相同。记住这一点,我编写的大多数模板只包含内联函数,因为代码只是更短的方式(函数的主体也必须在标题中才能从多个.cpp中使用文件,因此它可能只会减慢解析速度。)

(理智的)编译器现在是否尝试内联所有函数?在实践中将内联成员函数定义为inline有什么好处(参见下面的示例)?从现在开始,我是否应该避免在模板中编写内联函数?

template <class Foo>
struct Bar {
    inline bool IsThereBenefitInDoingThis()
    {
        return 10 < system("exit `wget -q -o - "
            "http://stackoverflow.com/questions/23789353/ | grep yes | wc -l`");
    }
};

2 个答案:

答案 0 :(得分:1)

一个简单的测试:

#include <math.h>
#include <stdio.h>

template <class T>
class Sine {
public:
#ifdef MAKEINLINE
    inline T Eval(T x)
#else // MAKEINLINE
    T Eval(T x)
#endif // MAKEINLINE
#ifdef PUTOUTSIDE
    ;
#else // PUTOUTSIDE
    {
        return T(sin(double(x)));
    }
#endif // PUTOUTSIDE
};

#ifdef PUTOUTSIDE
template <class T>
#ifdef MAKEINLINE
inline T Sine<T>::Eval(T x)
#else // MAKEINLINE
T Sine<T>::Eval(T x)
#endif // MAKEINLINE
{
    return T(sin(double(x)));
}
#endif // PUTOUTSIDE

int main(int argc, const char **argv)
{
    printf("%g\n", Sine<float>().Eval(M_PI));
    printf("%g\n", Sine<double>().Eval(M_PI));
    return 0;
}

运行:

g++ Main.cpp -o testi -DMAKEINLINE -O1
g++ Main.cpp -o testn -O1
g++ Main.cpp -o testo -DPUTOUTSIDE -O1
g++ Main.cpp -o testoi -DMAKEINLINE -DPUTOUTSIDE -O1
diff testi testn
diff testi testo
diff testi testoi

显示testitesto之间的差异,因此只要主体在内部,它是否被声明inline似乎无关紧要,或者至少在这个简单的情况下并以g ++(GCC)4.6.4。请注意,增加优化级别会内联函数的所有版本,并且没有差异。

答案 1 :(得分:1)

您应该假设出于优化目的,编译器会忽略inline关键字,并决定自己内联的内容,并且当您为类成员函数使用内联表单时,同样的规则也适用。我不确切地知道哪些编译器在哪些情况下做了或不做,但标准声称它是一般规则,并且基于在线观看编译器课程的视频我相信它

然而,这并不意味着“内联”和“内联”。关键字或内联成员函数表单是无用的,或者要么没有后果。关键问题是将相关定义包含在头文件中是否有效。非内联定义不应该在头文件中 - 这样做可能会导致链接器错误(重复符号,其中定义作为多个cpp文件的一部分重复编译)。

因此,如果你想在头文件中定义一个内联或另一种形式(结果是更长的编译,因为定义被编译在多个cpp文件中,链接器丢弃了除一个版本之外的所有文件)。 / p>

那就是说,模板又有点不同了。我忘记了细节,但我认为模板默认情况下与inline定义类似 - 它在页头文件中完全定义模板肯定是有效的(通常是必要的)。< / p>