關於 C 中模板的顯示實參的匹配順序問題?

時間 2021-06-02 01:03:20

1樓:莊嚴

template

classT2,

class

T3>T3f

(T1a,

T2b)然後:

f

>(3L

,4);此時,double 和 3L同時試圖指定T1 的型別;然後,按照規定,顯式指定勝出,也就是 double勝出,long 失敗。所以傳入3L實際被轉換為double。可以這樣證明:

#include

#include

template

classT2,

class

T3>T3f

(T1a,

T2b)int

main

()若使用gcc,將看到輸出內容是: d。 (表示 double)。

顯示指定模板的型別引數的規則很簡單:就是按模板定義中的型別引數出現次序(左->右)匹配。

這裡還牽扯到函式返回型別的判定,規則更簡單:函式返回值的型別模板,只能顯式指定。

通常教程會明確提到以上兩點;綜合起來,通常教程會給出乙個例子,用來展現乙個慣用法:把函式的返回值,作為模板中的第1個型別引數,如:

#include

template

SumT

,typename

NumT1

,typename

NumT2

>SumT

my_sum

(NumT1n1,

NumT2n2)

intmain

()輸出結果是:188.5。

型別引數匹配過程是:

double 顯式指定(第乙個型別引數): SumT ;

99 隱式指定(第2個型別引數) NumT1 是 int ;

89.6 隱式指定 (第3個型別引數)NumT2 是 double;

《白話 C++》 583頁在講解「顯示指定模板引數」小節時,為了讓讀者更好理解這個慣用法,特意以C++的標準轉換為例,乾脆抄到這裡同樣有助記憶和理解:

……比如我們常用的 static_cast,用於將源型別資料強制轉換到目標型別,如果將它視為(注意,只是視為)乙個函式模板,則需要兩個型別佔位符:

template

TDst

,typename

TSrc

>TDst

&static_cast

(TSrc

&src_data

);其中TDst是目標型別,也是函式的返回值型別,TSrc是源型別,也是函式入參型別。接下來考慮如果需要將double強制轉換為int,可以這樣使用嗎?

inti

=static_cast

(23.4

);在函式過載中,編譯器不依賴返回型別以確定呼叫哪個函式。在模板函式生成的過程中,編譯器同樣不依賴返回值型別來產生什麼樣的函式。因此,沒辦法,必須明確指定返回值型別:

inti

=static_cast

(23.4

);// 只顯示指定TDst是int。

不過,C++ 14 開始,像這樣的簡單的模板函式,其返回值使用 auto 也是可以的:

#include

template

NumT1

,typename

NumT2

>auto

my_sum

(NumT1n1,

NumT2n2)

intmain

()也能正確輸出 188.5.

如果是C++11,那麼比較雞肋,可以這麼寫:

#include

template

NumT1

,typename

NumT2

>auto

my_sum

(NumT1n1,

NumT2n2)

->decltype(n1

+n2)// <--變化在這裡

intmain()

2樓:靈魂黯滅

我大概懂你的問題,我理解是模板推導只在宣告式起作用,而不會去查詢內部定義,所以返回值的型別必須顯示指定,而形參的型別可以根據呼叫時的引數直接進行推導

如果你非要靠形參型別推到返回型別,c11後有乙個decltype()配auto的寫法,不過也不能太複雜

3樓:arrayJY

先說結論:答案既不是(1)也不是(2),你給出的函式呼叫其實是無法編譯通過的。

你這樣的寫法實際上T1=double, T2=int, T3=?

原因如下:

模板引數的顯式指定優先於隱式推導。

你這種寫法無法推導出返回值的型別。(你顯式指定了T1,然後用引數推導了T2,然而T3無法被推導)

C++ Template 2nd:

手邊只有英文版,嘗試翻譯一下,翻譯的不好還請大家斧正。

1.3.1 返回值的模板引數

舉個例子,你可以宣告乙個函式,它的第三個模板引數型別為返回值型別:

template

typenameT2,

typename

RT>RTmax(T1

a,T2b

);然而,模板引數推導不會考慮返回值的型別[1],並且RT沒有出現在函式呼叫的引數當中,所以,RT無法被推導。

結論是,你必須顯式指定模板引數列表,比如像這樣:

template

typenameT2,

typename

RT>RTmax(T1

a,T2b

);...

::max

double

,double

>(4,7.2

)//正確,但冗長

另乙個途徑是只顯式指定第乙個引數,然後讓編譯器去推導剩下的引數。通常來說,你必須從前到後指定所有不能被隱式推導出的引數型別。因此,如果你調換上面列子中模板引數的順序,那你只需要指定返回值的型別。

template

typenameT1,

typename

T2>RTmax(T1

a,T2b

);...

::max

>(4,7.2

)//正確:返回值型別為double,T1、T2由編譯器推導

關於C中的符號 ?

時夢 int p 4 array 這裡 p是指向陣列的指標,所以在使用時要加兩個 如果想要把p定義為陣列應該用 int p 4 array 此時可以直接用 p 1 2 效果等價於 p 1 2 ps 有一點需要注意的是 在C和C 裡,對指標變數的宣告 和 都是識別符號的一部分 我曾經在這裡暈了好久 屠...

C 中的模板類宣告標頭檔案和實現檔案分離後,如何能實現正常編譯?

孫嘉成 把模板的宣告放在.h檔案中,實現放在.cpp檔案中,在main.cpp檔案中 include XX.cpp 同樣可以正常使用模板函式,但是這並不能實現您說的隱藏實現,只是表面上將宣告和實現分離了,沒什麼實際用處,只是看著好看一些,不建議使用。 zaoru 1.包含模型 常規寫法將實現寫在標頭...

關於c 類中的this問題,成員函式過載

薛丁格的貓 我覺得你可能有一點沒搞清楚 this應為Screen const,為一常量指標,所指位址不能改變 位址確實是不可變的,但是指標指向的內容並不是常量,this表示的是指標指向的內容,應該是可以修改的。你可以從這一方面理解一下。 C primer這附近似乎是表述有誤 By default,t...