inline 与 constexpr 函数


在调用函数时会有额外的资源负担,一些小函数,可以「建议」编译器设为 inline 内联,若建议被采纳,该函数会自动在调用点展现为代码,因为编译器需要其实现才能展开函数调用,inline 函数通常直接在标头文件中实现,例如:

math.h

inline int pow2(int num) { 
    return num * num; 
} 

int pow(int, int);

配合标头文件,可以如下实现pow函数本体:

math.cpp

#include "math.h"

int pow(int n, int p) {
    int r = 1; 

    for(int i = 0; i < p; i++) {
        r *= n;
    }

    return r; 
}

调用函数时不用任何改变,例如:

main.cpp

#include <iostream>
#include "math.h"
using namespace std;

int main() {
    int num = 0;
    int power = 0; 

    cout << "输入数值:"; 
    cin >> num; 

    cout << "输入次方:"; 
    cin >> power; 

    cout << num << " 平方:" << pow2(num) << endl
         << num << " 的 " << power << " 次方:" 
         << pow(num, power) 
         << endl; 

    return 0;
}

inline 函数只能建议编译器,建议不一定被采纳,例如递归函数无法在调用点展开,数千行的函数也不适合在调用点展开,如果编译器拒绝将函数展开,会视为一般函数进行编译,inline 的建议会被忽略。

如果函数够简单,简单到编译器可以推断出返回值,可以使用constexpr修饰,调用这类函数时,若能推断出值,编译器就会用值来取代调用,最简单的情况就是:

constexpr double Pi() {
    return 3.14159;
}

然而,也可以是依参数计算的结果,例如:

constexpr int addOne(int n) {
    return n + 1;
}

在调用时若是:

constexpr int r = addOne(100);

若编译器直接推断的 101 会取代addOne调用,也就是constexpr int r = 101来进行编译;使用constexpr修饰的函数,通常写在标头文件中。


展开阅读全文