異聞錄 using 對型別封裝所引發的混亂

2021-10-11 12:26:38 字數 3991 閱讀 2345

起源

寫了一段**,然後出現報錯,嗯,陽光明媚,世界那麼好。

一瞬間,魔法迴路 (腦洞) 產生出我的第一解決方案:

(既然 const reference 沒有,那我換 const_reference 來試試)

mystring

(const_reference ch,

int size)

? emmm…

它好了,它好了。。

*************** 假裝自己是分隔線 ***************

這就很難受了,使用 const_reference 沒有任何異常,但最開始的 const reference 使用後,報錯:

翻譯下:小夥子,你那裡沒有我要的的 (char, int) 建構函式。

。。但是我明明寫了啊。。

mystring

(const reference ch,

int size)

;

這不對嗎?為什麼不認呢?

既然如此,我只好縮小範圍,重新編寫了另乙個測試程式:

#include

using value_type =

char

;using reference = value_type&

;using const_reference =

const value_type&

;void

foo(

const reference ch)

intmain()

結果。。

這次比之前的要好多了,有具體的不接受的原因。

翻譯:

小夥子,你定義的 void foo() 明明是個 void foo(char& ch) 的,

結果非要引用 常量字元 !!!

於是我在下面,新增了引用字元變數的語句進行對比:

? aha, 問題已經鎖定。

問題の源頭

我使用通過 using 封裝後的資料型別 + const 進行組合使用,compiler 卻說我宣告的是非常量引用。

?

既然問題出在 compiler 無法識別到我,

那我就看看我寫的**,在 compiler 眼裡到底長什麼樣!

借助 cppinsights 這個**,我看到了 compiler 眼裡的**:

↓(被翻譯成了這樣)

void

foo(reference ch)

warning: 『const』 qualifier on reference type 『reference』 (aka 『char &』) has no effect [-wignored-qualifiers]

翻譯:警告:引用型別「reference」(又名「char&」)上的「const」限定符沒有效果[-wignored修飾符]

大意就是說:

const 無法對 char& 這樣的組合進行修飾 … ?

? 啊,對啊,

char & 是表示 引用型別,但我使用 const 來對 (char&) 這樣的引用型別進行修飾,

能表示什麼呢???

頂多達到類似於這種的效果:char & const

但是,c++ 中 const 根本不會去修飾乙個引用型別,因為引用型別就是乙個 名字,你修飾它幹嘛,名字又無法被修改,頂多是給名字別後的實體,再換另乙個名字!!!

大致的結論

using 封裝的資料型別,會被當做成體來處理,而不是像 巨集 那樣,只是替換。

const reference的本意是:

const char &==> 乙個引用 const char 型別的引用,

但是,真正的實現則是:

char & --> const修飾 乙個引用了 char 型別的引用,但由於 const 修飾 引用是沒有任何意義的,

所以 const 被去除!

同理,換成 指標 也是一樣的。

using pointer =

char*;

// 語義:乙個指向 char 型別的指標

using const_pointer =

const

char*;

// 語義:乙個指向 const char 型別的指標

const pointer // 語義:乙個指向 char 型別的 const 指標

驗證

總結:這次遇到的錯誤,根本之處是在於,使用 using 對型別進行封裝之後,再和其它 c++ 中的型別限定符進行組合,最終導致了 c++ 語義上的錯誤。

通過 using 封裝後的型別,再被其他修飾符修飾時,封裝的型別不會按照像巨集一樣的規則,去直接展開,

而是,只放出封裝的資料型別中的最終展示者。

說人話:

using reference =

char&;

// 那麼,reference 在被呼叫時,展示者就是 & 引用

using const_pointer =

const

char*;

// 展示者:* 指標

大家加油 : )