2013-03-17 42 views
11

考慮這個函數模板:扣除類型後,函數模板中的替換順序是否有保證?

template<typename T> 
typename soft_error<T>::type foo(T, typename hard_error<T>::type) 
{ } 

從調用foo()的第一個參數的類型推斷類型T後,編譯器會進行替代T和實例函數簽名。

如果首先執行替換返回類型,導致簡單替換失敗,則編譯器將在計算重載集合並搜索其他可行超載(SFINAE)時放棄此函數模板。另一方面,如果第一個函數參數的替換先發生,導致硬錯誤(例如,由於非直接上下文中的替換失敗),則整個編譯將失敗。

問題:對函數參數和返回類型進行替換的順序是否有保證?


注:This example似乎表明,在所有主要的編譯器(VC11是單獨測試,並給了相同的結果)取代的返回類型替代參數類型之前發生。

+0

請注意,[遲到指定返回類型會改變事物](http://liveworkspace.org/code/4cvdpz%2464)。 – 2013-03-17 15:29:19

+0

@NicolBolas:對,這是因爲替代實際上是要按照詞彙順序發生 - 順便說一句Xeo正確地指出,這不是現行標準規定的行爲,所以我更正了我的答案 – 2013-03-17 15:33:09

回答

14

[注:此原本並不意味着是一個自我回答的問題,但我偶然發現瞭解決方案,同時各具特色的問題]


有沒有任何保證的爲函數參數和返回類型執行替換的順序?

不符合當前標準。

然而,this Defect Report(禮貌Xeo)表明,這確實是打算如此。下面是段落的C++ 11標準的14.8.2/7所提出的新的措辭(這已成爲n3485 draft的一部分):

在所有類型和表達被在函數中使用時的取代鍵入並在模板 參數聲明中。這些表達式不僅包含常量表達式,如 數組邊界或非類型模板參數中出現的常量表達式,還包含sizeof,decltype和允許非常量表達式的其他上下文中的常規表達式(即非常量表達式) 。 替換按詞彙順序進行 ,並在遇到導致扣除失敗的條件時停止。 [...]

作爲正確地評價的問題指出的Nicol Bolas詞彙順序意味着一個後返回類型將後的參數類型被取代,如圖this live example

+1

這真的很好。感謝分享這個。 +1來問答。 – Nawaz 2013-03-17 17:54:54