C reference 那些容易被忽視的細節

2021-10-22 10:24:45 字數 4768 閱讀 5875

工作之餘做個小結。(te為實體型別,td為推斷型別)

引用建立時即初始化賦值。作為函式引數時,程式進入函式就已經初始化完畢。

注意區分值與值的引用。

一旦創造了te&& t右值引用便有了別名,t的行為變成左值(傳入td&&模板為左引用,),但t列印出的型別依然為右值引用是別名,構造好的引用可當作自身,引用之間的非初始化賦值看const,非const引用像常量一樣任意賦值。const引用不能賦值。

引用的初始化賦值,比較複雜:對於te&&:僅能用右值初始化(對於非右值使用forward和move轉化)。te&能用左值,左值引用和右值引用初始化。

對於初始化賦值和正常函式引數繫結,規則是相似的:左值引用只能繫結左值右值引用只能繫結右值左值常量引用是個例外(可以繫結左值)

對於模板中的通用引用td&& t, 若直接用td和t, 則覆蓋了foward的合理情況。(通用引用模板相當於生成te&&和te&兩個模板,由於分別給左值和右值)。

std::forward 的作用為:條件轉化為右值,一般在含通用引用的模板中使用:

std::forward(t)的轉化依賴type型別:

// forward的其中乙個實現

template

<

typename tp>

forward

(typename remove_reference

::type& _t) no except

//其完整的行為如下(不考慮const)

std::forward(.

..)=

> te&&

(tp = te)總轉化為右值,結合其定義會令人困惑

std::forward>

(te&)=

> te&

(tp = te&

, 有 &

&&==&)

std::forward>(.

..)=

> te&&

(tp = te&&

, 有 &&

&&==&&)

//其餘非法forward(te&&),不能將右值forward為左值引用

在含td&&模板中,很好的適配type-deduction:

template

<

typename t>

void

foo(t&& t)

t的型別為te或te&

,對應t型別為te&&或te&

,forward對應forward型別te&&

,te&,見附錄。

te&&

-> te&&

const te&

->

const te&

te&/te -

> te&

const te&& 不是特別make sense,在對const 使用std::move和移動建構函式很違反邏輯,為什麼能移動卻叫const呢?而且const-rvalue-ref能做的const-lvalue-ref也能做。搜盡資料,const-rvalue-ref運用的地方有:

template

<

class

t>

void

ref(

const t&&)=

delete

;//同cref

這是我思考的一種情形,不知道有沒有應用場景。乙個類disable了複製建構函式,但enable移動建構函式,此時需要繫結const t&&用於構造const型別

class

example;}

;const example e;

const example movee

(std::

move

(e))

;//此時匹配const t&&

對於需要type-deduction的地方為universial reference。

對於實體型別,為rvalue reference。

template

<

typename t>

void

func

(std::remove_reference

::type&& t)

// is rvalue ref, not universal ref

注:有名字的右數值引用用te&&表示,右值代指無名的變數。

// 以下初始化賦值成立(同理函式引數繫結也一樣規則):

te&<

- te,te&

,te&&

const te&

<

- te,te&

,te&&

,const te,

const te&

,const te&&

,右值te&&

<

- std::

forward

(te&&

),右值

const te&&

<

- std::

forward

(te&&

),std::

forward

(const te&&

),右值

// 以下非初始化賦值成立

te&<

- te,

const te,te&

,const te&

,te&&

,const te&&

,右數值

te&<

- te,

const te,te&

,const te&

,te&&

,const te&&

,右數值

一般情況

int

&& rr =

1; rr =

>

int&& 但行為像int

&int

& r = rr; r =

>

int&

std::forward<

int>(.

..) ret =

>

int&&

std::forward<

int&

>

(te&

) ret =

>

int&

std::forward<

int&&

>(.

..) ret =

>

int&&

//其餘(t=te&,t=te&&)非法

td&&的模板

template

void

func

(t&& t)

int v =1;

int& r = v;

int&& rr =1;

//型別: t t forward(t)

func(1

):intint

&&int

&&func

(v):

int&

int&

int&

func

(r):

int&

int&

int&

func

(rr)

:int

&int

&int

&func

(std::forward<

int>

(rr)):

intint

&&int

&&

te&&的函式

void

func

(int

&& t)

;//僅能通過如下呼叫:

func(1

);func

(std::

move

(a))

;func

(std::forward<

int>

(a))

;

td&的模板(注意t和forward,在此模板不要隨便用forward)

template

void

func

(t& t)

int v =1;

int& r = v;

int&& rr =1;

//型別: t t forward(t)!!!(attention)

func(1

): no

func

(v):

intint

&int

&&func

(r):

intint

&int

&&func

(rr)

:int

int&

int&&

func

(std::forward<

int>

(rr)

): no

為你解析那些容易被大家忽視的電腦小細節

今天我們就針對電腦中大家平時忽略的一些電腦部件所需注意事項作乙個小總結。一 鍵盤 它怕潮氣 灰塵 拉拽。現在大部分的鍵盤都採用塑料薄膜開關,即開關由三張塑料薄膜構成,中間一張是帶孔的絕緣薄膜,兩邊的薄膜上鍍上金屬線路和觸點,受潮腐蝕 沾染灰塵都會使鍵盤觸點接觸不良,操作不靈。託拽易使鍵盤線斷裂,使鍵...

容易被忽略的羅大佑歌曲

剛才跟michael聊天,說起羅大佑,他說不熟。我說我肯定能找出10首歌,你知道,但你不知道是羅的歌。果然,我一說,他說 這也是他的 太牛x了 看來得給大家掃掃盲了,列幾首你可能很熟悉,但卻不一定知道是羅氏歌曲的歌 童年 沒聽過的童年的恐怕沒有,但不知道童年是羅大佑作品的還真的有。此歌最早由張艾嘉演...

2014容易被淘汰的人(共勉)

對於任何乙個人來說,總是要讓自己不斷的進 步才能適應社會的發展,那麼在2014年,哪些 人最容易被淘汰呢?一 八小時之外不學習的人 胡適先生說 人與人的區別在於八小時之 外如何運用。有時間的人不能成功,擠時間的 人才能成功。八小時之內決定現在,八小時之 外決定未來。什麼樣的想法什麼樣的生活。有 學習...