我認爲模板的定義是錯誤的,在這兩種情況下你都會觸發精確的遞歸。我本來期望的編譯器,而是產生了不同的錯誤,編譯器裏面的一些計算器死......
的are_same
可變參數模板的實現可能是:
template <class... Args> // base (optional to declare the template)
struct are_same;
template <class A, class B, class... Args> // recursion
struct are_same<A,B,Args...> {
static const bool value = is_same<A,B>::value && are_same<A,Args...>::value;
};
template <class A, class B> // stop condition
struct are_same<A,B> {
static const bool value = is_same<A,B>::value;
};
注意的是,在recursion
步,從參數列表中刪除一個參數,以便解決的新問題是原始版本的減少版本。這種類型的模板元編程與遞歸非常相關,並且適用相同的規則,以便能夠使用您需要的遞歸來確保每個遞歸步驟使您更接近解決方案。在這種特殊情況下,給出一個N個潛在相同類型的列表,每個步驟都會減少問題,以找出N-1類型是否相同。
您也可以使用,如停止條件(替換前一個)are_same
問題的退化版本:
template <class A>
struct are_same<A> {
static const bool value = true;
};
這是退化在這個意義上,它並沒有真正意義詢問是否一個類型* are_same *,但對於不同的元編程任務它可能是合適的。
不同的潛在的更有效的算法(我不知道編譯器是否會避免在上面的遞歸步驟的模板實例化),不依賴於is_same
可能是:
template <class... Args>
struct are_same;
template <class A, class... Args>
struct are_same<A,A,Args...> { // recursion
static const bool value = are_same<A,Args...>::value;
};
template <class A, class B, class... Args>
struct are_same<A,B,Args...> { // cut, A and B are not the same
static const bool value = false;
};
template <class A>
struct are_same<A> { // end of recursion
static const bool value = true;
};
在這種情況下, ,只要兩種類型相同,編譯器會更喜歡recursion
到cut
步驟,所以我們不需要在內部檢查is_same
。同時,如果編譯器進入cut
步驟,我們不需要處理類型列表的其餘部分,因爲我們已經知道答案。
這是一個驚人的輝煌,尤其是「短路」的一步。謝謝。 – smallB
不錯,但是在第一個代碼片段中有一個小錯誤。應該是'static const bool value = is_same :: value && are_same :: value;' –
@VJo:它們完全一樣,一旦您證明'A == B',與''或' ''''根本沒有關係,也沒有任何優勢,你觸發了一個新的模板實例,並且此時編譯器將解析'A'和'B'的類型(即int ','double' ...),這兩段代碼完全一樣。 –