[英]SFINAE and partial class template specializations
我已經使用基於SFINAE的方法已經有一段時間了,特別是通過std::enable_if
來啟用/禁用特定的類模板特化。
因此,在閱讀描述擬議的void_t
別名/檢測慣用語的論文時,我有點困惑:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf
第4節專門討論成語的有效性,並參考了一個討論,其中兩方爭論SFINAE在部分類模板專業化中的適用性(理查德史密斯指出該標准缺乏關於該主題的措辭) 。 在本節末尾,提到了以下CWG問題
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2054
這里再次聲明該標准沒有明確地允許在該問題中再現的示例。
我有點困惑,因為在我看來,例如,在部分特化中使用enable_if
已經有一段時間的標准做法(例如參見Boost文檔,它明確提到了部分特化)。
我誤解了上述文件中的要點還是真的是灰色區域?
我想爭辯說,由於措辭缺陷,標准不支持部分專業化的SFINAE。 讓我們從[temp.class.spec.match]開始:
如果可以從實際模板參數列表推導出部分特化的模板參數,則部分特化匹配給定的實際模板參數列表(14.8.2)。
並且,從[temp.deduct],SFINAE條款:
如果替換導致無效的類型或表達式,則類型推導失敗。 如果使用替換參數寫入,則無效的類型或表達式將是格式錯誤的,需要診斷。 [注意:如果不需要診斷,程序仍然是不正確的。 訪問檢查是替換過程的一部分。 -end note]只有函數類型的直接上下文中的無效類型和表達式及其模板參數類型才會導致演繹失敗。
來自CWG的略微修改的示例†是:
template <class T, class U> struct X {
typedef char member;
};
template<class T> struct X<T,
typename enable_if<(sizeof(T)>sizeof(
float)), float>::type>
{
typedef long long member;
};
int main() {
cout << sizeof(X<char, float>::member);
}
X
上的名稱查找找到主要內容, T == char, U == float
。 我們看一個部分特化,看看它是否“匹配” - 這意味着模板參數“可以推導出” - 也就是說:
+-------------+--------+-------------------------------------------------+
| | arg1 arg2 |
+-------------+--------+-------------------------------------------------+
| deduce T in | T | enable_if_t<(sizeof(T) > sizeof(float), float> |
| from | char | float |
+-------------+--------+-------------------------------------------------+
正常的模板扣除規則適用。 第二個“參數”是一個不可推導的上下文,因此我們將T
推導為char
。 sizeof(char) > sizeof(float)
,為false,並且enable_if_t<false, float>
是無效類型,因此類型推導應該失敗...但是,只能進行扣減失敗
在函數類型及其模板參數類型的直接上下文中
我們沒有處理函數類型或函數模板參數類型,我們正在處理類模板參數類型。 一個類不是一個函數,所以如果我們從字面上理解所有內容,SFINAE排除不應該適用 - 並且修改后的CWG示例應該導致硬錯誤。
然而,規則的精神似乎更符合以下方面:
只有扣除過程的直接上下文中的無效類型和表達式才會導致扣減失敗。
我不知道具體排除類部分專業化演繹的原因是什么。 此外,類模板部分特化的部分排序也看起來像函數。 來自[temp.class.order]:
對於兩個類模板部分特化,第一個比第二個更專業,如果給出以下重寫到兩個函數模板 ,[...]
因此,標准已經在下一部分中展示了類模板部分特化和功能模板之間的二元性。 事實上,這僅適用於部分特化排序,而不是在部分特化參數推導期間的替換失敗,這使我感到有缺陷。
†示例本身是X<double, float>
。 但這實際上並沒有證明或要求SFINAE,因為任何地方都不會有替代失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.