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

C++ 引用折疊(Reference Collapsing)的具體使用

 更新時(shí)間:2026年05月19日 09:15:07   作者:點(diǎn)云SLAM  
本文主要介紹了C++ 引用折疊使用,,引用折疊主要在模板類型推導(dǎo)、auto、decltype等場(chǎng)景中發(fā)生,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一句話定義
當(dāng)“引用的引用”在模板、typedef / using、auto、decltype 中出現(xiàn)時(shí),
編譯器按照固定規(guī)則把它折疊為單一引用類型。

一、為什么需要引用折疊?

C++ 語(yǔ)法層面 不允許顯式寫

int&&& x;   //  非法

但在模板推導(dǎo)后,這種“引用的引用”會(huì)隱式產(chǎn)生

template<typename T>
void f(T&& x);

當(dāng)這樣調(diào)用:

int a;
f(a);       // T = int&

于是參數(shù)類型變成:

T&& → int& &&   ← 出現(xiàn)“引用的引用”

引用折疊規(guī)則的存在目的:

讓模板推導(dǎo)在語(yǔ)法上始終合法

二、唯一的折疊規(guī)則

C++ 標(biāo)準(zhǔn)中的核心規(guī)則

只要出現(xiàn)左值引用 &,最終結(jié)果就是 &
只有 && && 才會(huì)折疊成 &&

四種情況

原始形式折疊結(jié)果
T& &T&
T& &&T&
T&& &T&
T&& &&T&&

口訣版

“& 是霸道的,只要出現(xiàn)就贏”

三、引用折疊只會(huì)在這些地方發(fā)生

不是任何地方都會(huì)發(fā)生引用折疊

會(huì)發(fā)生的場(chǎng)景

  1. 模板類型推導(dǎo)
  2. using / typedef
  3. auto
  4. decltype
  5. std::forward / 完美轉(zhuǎn)發(fā)

不會(huì)發(fā)生的場(chǎng)景

int&& && x;     // 語(yǔ)法錯(cuò)誤(非模板上下文)

四、模板推導(dǎo)中的引用折疊(最重要)

1 萬(wàn)能引用(Forwarding Reference)

template<typename T>
void f(T&& x);

調(diào)用情況分析

int a = 10;
f(a);

推導(dǎo)過(guò)程:

T = int&
T&& = int& && → 折疊 → int&

x左值引用

f(10);
T = int
T&& = int&&

x右值引用

結(jié)論(非常重要)

T&& 在模板中 ≠ 右值引用
它是 萬(wàn)能引用(forwarding reference)

五、auto中的引用折疊

示例 1:auto&&

int a = 10;
auto&& x = a;

推導(dǎo):

auto = int&
auto&& = int& && → int&
auto&& y = 10;
auto = int
auto&& = int&&

結(jié)論

auto&&   // 永遠(yuǎn)是萬(wàn)能引用

六、using / typedef中的引用折疊

示例

using LRef = int&;
using RRef = int&&;

LRef&   → int&
LRef&&  → int&
RRef&   → int&
RRef&&  → int&&

using 不會(huì)阻止引用折疊

七、decltype+ 引用折疊(最容易踩坑)

規(guī)則回顧

int x = 10;

decltype(x)      // int
decltype((x))    // int&   ← 注意括號(hào)!

示例

decltype((x))&& y = x;

推導(dǎo):

decltype((x)) = int&
int& && → int&

結(jié)論

decltype 的結(jié)果本身可能帶引用
再加 && 就會(huì)觸發(fā)引用折疊

八、完美轉(zhuǎn)發(fā) = 引用折疊 + 值類別保持

std::forward的本質(zhì)

template<typename T>
T&& forward(remove_reference_t<T>& param);

使用示例

template<typename T>
void wrapper(T&& arg) {
    foo(std::forward<T>(arg));
}

左值情況

T = int&
forward<int&>(arg) → int&

右值情況

T = int
forward<int>(arg) → int&&

引用折疊是完美轉(zhuǎn)發(fā)成立的核心機(jī)制

九、常見(jiàn)錯(cuò)誤 & 工程級(jí)坑點(diǎn)

誤以為T&&一定是右值引用

template<typename T>
void f(T&& x);   //  錯(cuò)

正解:

當(dāng)且僅當(dāng) T 是被推導(dǎo)出來(lái)的,T&& 才是萬(wàn)能引用

在非模板中使用&&期望折疊

void f(int&&&& x);  // 

忘了decltype((x))是引用

十、編譯器視角總結(jié)

引用折疊不是運(yùn)行期行為
它發(fā)生在模板實(shí)例化 + 類型替換階段

編譯流程中位置

模板推導(dǎo)
→ 生成候選類型
→ 引用折疊
→ 最終參數(shù)類型
→ 代碼生成

十一、終極總結(jié)

1?? 引用折疊只在模板/類型推導(dǎo)中發(fā)生
2?? 規(guī)則只有一條:有 & 就是 &
3?? T&& + 模板推導(dǎo) = 萬(wàn)能引用
4?? 完美轉(zhuǎn)發(fā)的底層機(jī)制 = 引用折疊
5?? decltype((x)) 是最常見(jiàn)陷阱

Eigen/SLAM 中:引用折疊如何避免拷貝

一、Eigen 場(chǎng)景中的真實(shí)問(wèn)題

在 SLAM 代碼中經(jīng)常會(huì)寫:

Eigen::Matrix<double, 15, 15> H;
Eigen::Matrix<double, 15, 1>  b;

或者:

Eigen::Vector3d r;
Eigen::Matrix3d J;

天真的接口(會(huì)拷貝)

void AddResidual(Eigen::VectorXd r) {
    // 每次調(diào)用都會(huì)拷貝
}

Eigen 動(dòng)態(tài)矩陣 → 昂貴拷貝

二、Eigen 官方的解決方案:模板 + 表達(dá)式

Eigen 的核心思想

Matrix = 表達(dá)式

表達(dá)式不是值,而是 Expression Template

三、錯(cuò)誤寫法 vs 正確寫法(關(guān)鍵對(duì)比)

錯(cuò)誤:值傳遞

template<typename Derived>
void AddResidual(Eigen::MatrixBase<Derived> r) {
    // 拷貝已經(jīng)發(fā)生
}

錯(cuò)誤:const 引用但阻斷右值

template<typename Derived>
void AddResidual(const Eigen::MatrixBase<Derived>& r);
  • 不能高效接收臨時(shí)表達(dá)式
  • 失去 move / lazy evaluation 的機(jī)會(huì)

四、Eigen 推薦的“零拷貝”接口寫法

核心模式(引用折疊的舞臺(tái))

template<typename Derived>
void AddResidual(Eigen::MatrixBase<Derived>&& r) {
    // 完美接收左值 or 右值
}

這是 Eigen 內(nèi)部大量使用的模式

五、引用折疊在這里如何工作?

情況 1:傳左值(已有殘差向量)

Eigen::Vector3d r;
AddResidual(r);

推導(dǎo)過(guò)程

T = Eigen::Vector3d&
T&& = Eigen::Vector3d& && → 折疊 → Eigen::Vector3d&

r左值引用 進(jìn)入
無(wú)拷貝

情況 2:傳右值表達(dá)式(Eigen 的精華)

AddResidual(J * dx + r0);

這里:

J * dx + r0  → Eigen::CwiseBinaryOp<...>(表達(dá)式)

推導(dǎo)過(guò)程

T = CwiseBinaryOp<...>
T&& = CwiseBinaryOp<...>&&

表達(dá)式對(duì)象 零拷貝傳入
計(jì)算 延遲到函數(shù)內(nèi)部

六、為什么const&在 Eigen 中不夠好?

問(wèn)題

const Eigen::MatrixBase<Derived>& r
  • 強(qiáng)制綁定 const
  • 阻止某些 move / eval
  • 某些表達(dá)式不能安全延遲

Eigen 官方風(fēng)格

template<typename Derived>
void foo(Eigen::MatrixBase<Derived>&& x);

并在內(nèi)部:

auto&& expr = std::forward<Derived>(x);

七、SLAM 后端:殘差 & Jacobian 的真實(shí)例子

一個(gè)真實(shí)的誤差項(xiàng)接口

template<typename ResidualDerived, typename JacobianDerived>
void AddFactor(ResidualDerived&& r,
               JacobianDerived&& J) {
    using RType = std::remove_reference_t<ResidualDerived>;
    using JType = std::remove_reference_t<JacobianDerived>;

    // 僅在必要時(shí) eval
    const RType& r_eval = r;
    const JType& J_eval = J;

    // 參與正規(guī)方程
}

調(diào)用方式(零拷貝)

AddFactor(
    J * dx + r0,          // 右值表達(dá)式
    J.transpose() * J     // 右值表達(dá)式
);

八、結(jié)合李代數(shù)(SO(3) / SE(3))

常見(jiàn) SLAM 代碼

template<typename TangentDerived>
void ApplyUpdate(TangentDerived&& delta) {
    // delta 是 Eigen::Matrix<double, 6, 1> 或表達(dá)式
    xi_ = Sophus::SE3d::exp(delta) * xi_;
}

左值情況

Eigen::Matrix<double, 6, 1> dx;
ApplyUpdate(dx);

delta 折疊為 Eigen::Matrix<...>&

右值情況

ApplyUpdate(H.ldlt().solve(b));

deltaEigen 表達(dá)式
無(wú)臨時(shí)矩陣拷貝

九、std::forward 在 Eigen / SLAM 中的作用

正確姿勢(shì)

template<typename Derived>
void Foo(Derived&& x) {
    Bar(std::forward<Derived>(x));
}

錯(cuò)誤姿勢(shì)

Bar(x);  // 丟失值類別 → 右值變左值

十、性能視角總結(jié)(非常重要)

寫法是否拷貝表達(dá)式延遲工程推薦
值傳遞??禁用
const&?部分一般
T&& + forward???????

十一、Eigen / SLAM 模板黃金法則

任何可能接收 Eigen 表達(dá)式 / 李代數(shù)增量的接口:

template<typename T>
void func(T&& x);

并在內(nèi)部:

auto&& v = std::forward<T>(x);

十二、在 SLAM 系統(tǒng)中應(yīng)該立刻用的模式

后端殘差

template<typename R, typename J>
void AddResidual(R&& r, J&& J) { ... }

狀態(tài)更新

template<typename DX>
void Update(DX&& dx);

圖優(yōu)化 factor 構(gòu)造

template<typename Measurement>
Factor(Measurement&& z);

總結(jié)

Eigen 的高性能 = 表達(dá)式模板
表達(dá)式模板的生命線 = 引用折疊 + 完美轉(zhuǎn)發(fā)

到此這篇關(guān)于C++ 引用折疊(Reference Collapsing)的具體使用的文章就介紹到這了,更多相關(guān)C++ 引用折疊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于C語(yǔ)言實(shí)現(xiàn)創(chuàng)意多彩貪吃蛇游戲

    基于C語(yǔ)言實(shí)現(xiàn)創(chuàng)意多彩貪吃蛇游戲

    這篇文章主要介紹了如何利用C語(yǔ)言實(shí)現(xiàn)一個(gè)創(chuàng)意多彩貪吃蛇游戲,這是一個(gè)純C語(yǔ)言外加easyx庫(kù)的繪圖函數(shù)制作而成的有趣小游戲,無(wú)需引入額外資源,感興趣的可以動(dòng)手嘗試一下
    2022-08-08
  • opencv3/C++ 將圖片轉(zhuǎn)換為視頻的實(shí)例

    opencv3/C++ 將圖片轉(zhuǎn)換為視頻的實(shí)例

    今天小編就為大家分享一篇opencv3/C++ 將圖片轉(zhuǎn)換為視頻的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • VS?Code+msys2配置Windows系統(tǒng)下C/C++開(kāi)發(fā)環(huán)境

    VS?Code+msys2配置Windows系統(tǒng)下C/C++開(kāi)發(fā)環(huán)境

    我們?cè)趙indows10中使用VS Code做C++程序開(kāi)發(fā)過(guò)程中,需要安裝MSYS2和MinGW,下面這篇文章主要給大家介紹了關(guān)于VS?Code+msys2配置Windows系統(tǒng)下C/C++開(kāi)發(fā)環(huán)境的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • C語(yǔ)言中互斥鎖與自旋鎖及原子操作使用淺析

    C語(yǔ)言中互斥鎖與自旋鎖及原子操作使用淺析

    今天不整GO語(yǔ)言,我們來(lái)分享一下以前寫的C語(yǔ)言代碼,來(lái)看看互斥鎖、自旋鎖和原子操作的demo,示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值
    2023-01-01
  • 淺析內(nèi)存對(duì)齊與ANSI C中struct型數(shù)據(jù)的內(nèi)存布局

    淺析內(nèi)存對(duì)齊與ANSI C中struct型數(shù)據(jù)的內(nèi)存布局

    當(dāng)在C中定義了一個(gè)結(jié)構(gòu)類型時(shí),它的大小是否等于各字段(field)大小之和?編譯器將如何在內(nèi)存中放置這些字段?ANSI C對(duì)結(jié)構(gòu)體的內(nèi)存布局有什么要求?而我們的程序又能否依賴這種布局
    2013-09-09
  • C++ 私有析構(gòu)函數(shù)的作用示例詳解

    C++ 私有析構(gòu)函數(shù)的作用示例詳解

    這篇文章主要介紹了C++ 私有析構(gòu)函數(shù)的作用,私有析構(gòu)函數(shù)不會(huì)影響棧上對(duì)象的自動(dòng)析構(gòu),它們會(huì)在其作用域結(jié)束時(shí)自動(dòng)調(diào)用析構(gòu)函數(shù)。私有析構(gòu)函數(shù)主要影響的是對(duì)堆上對(duì)象的顯式刪除操作,需要的朋友可以參考下
    2023-06-06
  • VC創(chuàng)建DLL動(dòng)態(tài)鏈接庫(kù)的方法

    VC創(chuàng)建DLL動(dòng)態(tài)鏈接庫(kù)的方法

    這篇文章主要介紹了VC創(chuàng)建DLL動(dòng)態(tài)鏈接庫(kù)的方法,實(shí)例分析VC創(chuàng)建動(dòng)態(tài)鏈接庫(kù)的完整步驟,需要的朋友可以參考下
    2015-05-05
  • C語(yǔ)言實(shí)現(xiàn)冒泡排序算法的示例詳解

    C語(yǔ)言實(shí)現(xiàn)冒泡排序算法的示例詳解

    這篇文章主要介紹了C語(yǔ)言如何實(shí)現(xiàn)冒泡排序算法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 關(guān)于C++動(dòng)態(tài)分配內(nèi)存的介紹

    關(guān)于C++動(dòng)態(tài)分配內(nèi)存的介紹

    今天小編就為大家分享一篇關(guān)于關(guān)于C++動(dòng)態(tài)分配內(nèi)存的介紹,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • C語(yǔ)言實(shí)現(xiàn)飛機(jī)大戰(zhàn)

    C語(yǔ)言實(shí)現(xiàn)飛機(jī)大戰(zhàn)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)飛機(jī)大戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06

最新評(píng)論

特克斯县| 万山特区| 寿阳县| 乐至县| 桑植县| 清新县| 团风县| 东城区| 扎赉特旗| 柳河县| 兴安盟| 新干县| 江达县| 新平| 浪卡子县| 镇康县| 疏附县| 名山县| 泰安市| 利川市| 黑山县| 新竹县| 建宁县| 伊通| 盐边县| 于都县| 瓦房店市| 杭锦后旗| 隆昌县| 兴仁县| 吉林省| 江油市| 准格尔旗| 仁寿县| 龙川县| 屯留县| 民县| 绥化市| 东乡族自治县| 新民市| 当阳市|