最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ 內聯函數inline Function示例詳解

 更新時間:2025年11月24日 09:35:03   作者:點云SLAM  
文章介紹了C++內聯函數的含義、內聯展開、編譯器何時內聯以及內聯對鏈接和性能的影響,內聯函數允許在頭文件中定義函數,以避免ODR錯誤,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧

1. 內聯函數的本質

C++ 中的 inline 有兩個含義:

(1) 允許函數在多個翻譯單元中重復定義

用于放寬 ODR(One Definition Rule)。
→ 這是 inline 最重要的實際用途。

(2) 作為性能優(yōu)化提示

告訴編譯器“可以內聯展開”。
→ 編譯器可以忽略,不是強制。

2. 內聯展開是什么?

通常函數調用包含跳轉、壓棧、返回等開銷。
內聯展開 = 把函數代碼直接拷貝到調用點,避免調用開銷。

示例:

inline int sqr(int x) { return x * x; }

展開后等價于直接寫 x * x

3. 編譯器何時會內聯?

編譯器的優(yōu)化器根據啟發(fā)式決定:

會內聯的典型情況:

  • 函數很短(幾行)
  • 在頭文件定義(可見函數體)
  • 優(yōu)化級別 O2 / O3
  • constexpr、模板、類內定義成員(均“傾向內聯”)

不會內聯的情況:

  • 遞歸函數
  • 虛函數(除非去虛化)
  • 大型函數(幾十行以上)
  • 啟用 O0 無優(yōu)化
  • 編譯器認為會導致代碼膨脹(ICache Miss 風險)

4. inline 對鏈接的影響

普通函數只能在一個 .cpp 中定義,否則多重定義錯誤。

但 inline 函數可以這樣:

// foo.h
inline int add(int a, int b) { return a + b; }

然后出現在多個 cpp 中,鏈接器會合并。

類內定義的函數默認 inline,因此類成員函數出現在頭文件是合法的。

模板函數也是同理(模板必須寫在頭文件)。

5. inline vs 宏

對比項inline
類型檢查
作用域文本替換
調試支持
常見用途小函數簡單表達式、條件編譯

一般規(guī)則:能用 inline,就不要用宏。

6. inline 對性能的真實影響

正面:

  • 消除函數調用成本(主要在小函數中有效)
  • 觸發(fā)更多優(yōu)化(常量傳播、死代碼刪除)

負面:

  • 代碼膨脹,可能讓指令緩存命中率下降 → 性能變差
  • 大函數內聯通常是負優(yōu)化

因此:

內聯最有效的場景:頻繁調用的小函數(數學計算、向量操作)。

(Eigen、Sophus、GTSAM 都這么做)

7. 工程中內聯的推薦模式

應當內聯:

  • 小函數(特別是數學運算)
  • getter/setter
  • 模板函數
  • 類內定義成員函數
  • 簡單內存操作和判斷邏輯

不要內聯:

  • 復雜流程函數(ICP、優(yōu)化殘差、求導)
  • 大循環(huán)
  • 虛函數
  • 調試時需要斷點的復雜函數

8. 常見誤區(qū)

誤區(qū) 1:加 inline 就會內聯

事實:編譯器完全可以忽略。

誤區(qū) 2:內聯一定加速

事實:大函數內聯反而變慢。

誤區(qū) 3:inline 主要用來優(yōu)化性能

事實:inline 的核心用途是允許頭文件重復定義函數。

9. 精簡總結

  • inline = “允許多次定義” + “可選擇性內聯展開”
  • 編譯器才最終決定是否真正內聯
  • 用于頭文件小函數非常合適
  • 濫用會導致代碼膨脹和性能下降
  • 函數越短越可能被內聯

10.C++ 內聯函數綜合示例

1.最常用:類內定義 = 默認內聯

class Vec3 {
public:
    double x, y, z;
    // 類內定義 → 默認 inline
    double norm2() const { 
        return x * x + y * y + z * z; 
    }
    void scale(double s) {
        x *= s; y *= s; z *= s;
    }
};

特點:

  • 類內定義的函數自動成為 inline
  • 在頭文件中使用時不會導致 ODR 沖突
  • 常用于 getters/setters、小數學操作(SLAM 中大量使用)

2.類外定義 but 內聯:適用于頭文件工具函數

// vec_utils.h
#pragma once
inline double dot(const Vec3& a, const Vec3& b) {
    return a.x*b.x + a.y*b.y + a.z*b.z;
}

為什么要 inline?

因為頭文件中定義函數,如果不 inline → 多重定義。

適合:數學工具函數、小型轉換函數、小 lambda 替代。

3.模板函數天然 inline

SLAM & 點云處理中大量用的模板代碼本質都是 inline:

template<typename T>
inline T clamp(T v, T lo, T hi) {
    return (v < lo) ? lo : (v > hi) ? hi : v;
}

其實模板函數不寫 inline 也能 inline,因為:

  • 模板必須放頭文件
  • 每個 TU 都需要實例化
  • 編譯器會自動當成 inline 處理

4.內聯 + constexpr(超輕量函數最佳組合)

constexpr inline double deg2rad(double deg) {
    return deg * 3.14159265358979323846 / 180.0;
}

用途:

  • 編譯期數學常量
  • 小型轉換函數
  • 角度/弧度轉換(SLAM 必備)

5.內聯 setter / getter

強烈推薦用于性能敏感代碼(尤其是數學類型/幾何類):

class Pose {
public:
    inline double x() const { return tx; }
    inline void setX(double v) { tx = v; }
private:
    double tx;
};

現代 C++ get/set 可 inline 解決跳轉開銷。

6.內聯 + forceinline 強制內聯(GCC/Clang/MSVC)

對于高度性能敏感的代碼(例如點云 ICP 內循環(huán)):

#if defined(_MSC_VER)
#define FORCE_INLINE __forceinline
#else
#define FORCE_INLINE __attribute__((always_inline)) inline
#endif
FORCE_INLINE double sqr(double x) { return x * x; }

注意:

  • 濫用會導致代碼膨脹(影響指令緩存)
  • 建議用于極短(1~3 行)的小函數

7.與 static inline 結合用于 header-only 工具庫

可避免 ODR 沖突:

// math_utils.h
#pragma once
static inline double fast_min(double a, double b) {
    return (a < b) ? a : b;
}

推薦場景:
頭文件單獨工具函數,但不希望暴露全局符號。

8.類模板內聯成員函數(Eigen, Sophus, SLAM 常用寫法)

template<typename T>
class Box {
private:
    T min_, max_;
public:
    inline T size() const { return max_ - min_; }
    inline bool contains(const T& x) const { return x >= min_ && x <= max_; }
};

典型用途:Bounding box、SE(3)、SO(3) 數學類型等。

9.內聯函數的真實性能對比(示例)

非內聯版本(有函數調用開銷)

double sqr(double x) { return x*x; }
double sum(const std::vector<double>& v) {
    double s = 0;
    for(double x : v) s += sqr(x);
    return s;
}

編譯器可能無法展開(尤其跨文件編譯時)。

內聯版本(更易優(yōu)化)

inline double sqr(double x) { return x*x; }

優(yōu)勢:

  • 去掉調用開銷
  • 可進行循環(huán)展開 / SIMD 優(yōu)化
  • 能被進一步優(yōu)化為 x*x 的常量傳播

10.完整示例:內聯 + 模板 + 內聯類成員

這是一個仿 SLAM 庫的小型數學類型示例:

#pragma once
#include <cmath>
class Vec3 {
public:
    double x, y, z;
    inline Vec3(double X, double Y, double Z)
        : x(X), y(Y), z(Z) {}
    inline double dot(const Vec3& o) const {
        return x*o.x + y*o.y + z*o.z;
    }
    inline Vec3 operator+(const Vec3& o) const {
        return Vec3(x+o.x, y+o.y, z+o.z);
    }
    inline Vec3 normalized() const {
        double n = std::sqrt(dot(*this));
        return Vec3(x/n, y/n, z/n);
    }
};
// 工具函數(header-only)
inline double distance(const Vec3& a, const Vec3& b) {
    return (a + Vec3(-b.x, -b.y, -b.z)).normalized().dot(a);
}

這是 SLAM / ICP / 點云算法中常見的數學類寫法:
全都 inline,以消除函數開銷,加速內循環(huán)。

小結:內聯函數的最佳工程實踐

場景是否 inline
類內部定義自動 inline,推薦
頭文件小工具函數必須 inline
模板函數自動 inline, OK
性能敏感數學函數inline 或 forceinline
大型函數不推薦(代碼膨脹)
接口函數(虛函數)不能 inline

到此這篇關于C++ 內聯函數(inline Function)詳解的文章就介紹到這了,更多相關C++ 內聯函數內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 在vs2017上配置AppGameKit庫的圖文教程

    在vs2017上配置AppGameKit庫的圖文教程

    這篇文章主要介紹了在vs2017上配置AppGameKit庫的教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • C語言基礎野指針與空指針示例分析

    C語言基礎野指針與空指針示例分析

    全網最接地氣的C語言野指針介紹,此處對于野指針與空指針知識點做一些簡要的介紹,作者實屬初學,難免文章中有內容理解不到位或者有不當之處,還請朋友們不吝指正,希望大家多多給予支持
    2021-11-11
  • 詳解CLion配置openMP的方法

    詳解CLion配置openMP的方法

    這篇文章主要介紹了CLion配置openMP的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • Qt實現Slider滑塊條組件的示例代碼

    Qt實現Slider滑塊條組件的示例代碼

    在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,本文主要介紹了Qt實現Slider滑塊條組件的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • 帶你了解C++中vector的用法

    帶你了解C++中vector的用法

    大家好,本篇文章主要講的是帶你了解C++中vector的用法,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C++?AVL樹的兩單旋和兩雙旋的項目實踐

    C++?AVL樹的兩單旋和兩雙旋的項目實踐

    本文主要介紹了C++?AVL樹的兩單旋和兩雙旋的項目實踐,根據節(jié)點插入位置的不同,AVL樹的旋轉分為四種,下面就來介紹一下,感興趣的可以了解一下
    2024-03-03
  • C++簡明分析講解引用與函數提高及重載

    C++簡明分析講解引用與函數提高及重載

    今天繼續(xù)開始對C++核心編程知識的分享與系統講解,第一,這里會提到“引用”方法傳參以及剖析引用的本質;第二,我們對函數來一個提高,相當于進階函數了,包括函數的默認值,簡單的提一下函數的占位參數,函數重載以及注意事項,接下來上正文
    2022-05-05
  • C++實現LeetCode(15.三數之和)

    C++實現LeetCode(15.三數之和)

    這篇文章主要介紹了C++實現LeetCode(三數之和),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-07-07
  • C語言數據輸入與輸出實例詳解

    C語言數據輸入與輸出實例詳解

    這篇文章主要介紹了C語言數據輸入與輸出實例詳解的相關資料,需要的朋友可以參考下
    2017-06-06
  • C++編寫的WebSocket服務端客戶端實現示例代碼

    C++編寫的WebSocket服務端客戶端實現示例代碼

    本文主要介紹了C++編寫的WebSocket服務端客戶端實現示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10

最新評論

济宁市| 门源| 桃源县| 星座| 巴彦淖尔市| 盐城市| 南昌县| 五莲县| 安阳市| 鲁山县| 宿州市| 中阳县| 武强县| 都兰县| 马尔康县| 兴海县| 牟定县| 衡阳县| 陆丰市| 林口县| 镶黄旗| 泽普县| 新密市| 清流县| 柳林县| 荥经县| 大庆市| 石屏县| 社旗县| 阿拉善右旗| 体育| 普兰县| 蚌埠市| 南宫市| 宁津县| 海晏县| 五常市| 涟源市| 西贡区| 肇源县| 洪湖市|