[英]Template arguments deduction for parameter type of function pointer involving non-deduced parameter pack
[英]Template arguments deduction for function parameter pack followed by other parameters
f1
和f2
的演繹是否形成不良?
template<class... T, class U>
void f1(T..., U){}
template<class... T>
void f2(T..., int){}
int main()
{
f1(1);
f2(1);
return 0;
}
g ++接受兩者,clang只接受f2
,而msvc拒絕這兩者。
相關標准措辭:
當函數參數包出現在非推導的上下文([temp.deduct.type])中時,永遠不會推導出該參數包的類型。
未推斷的上下文是:
- 函數參數包,不會出現在參數聲明列表的末尾。
所以似乎MSVC拒絕兩者都是正確的?
這是否意味着即使您明確指定模板args,模板的任何實例化都將是格式錯誤的?
f1<int>(1, 2); // ill-formed?
f2<int>(1, 2); // ill-formed?
如果是這樣的話,為什么要在第一時間允許這樣的聲明呢?
這個特定問題DR1388有一個DR。 顯然,似乎GCC和CLANG還沒有實現它CLANG DR1388 。
這是否意味着即使您明確指定模板args,模板的任何實例化都將是格式錯誤的?
f1<int>(1, 2); // ill-formed? f2<int>(1, 2); // ill-formed?
如果是這樣的話,為什么要在第一時間允許這樣的聲明呢?
否如果您明確指定模板參數,則不會發生扣減,因此上面顯示的代碼是合法的。
我自己研究過這個問題,我發現得到一個明確的答案是非常困難的。 我可以說, f1(1)
應該被拒絕但是f2(1)
應該被接受 。
那說:
正如您所指出的,未在列表末尾出現的函數參數包是非推導的上下文([temp.deduct.type] p5):
未推斷的上下文是:
- ...
- 函數參數包,不會出現在參數聲明列表的末尾。
和[temp.deduct.call] p1(通過CWG 1388修訂)澄清了從未推斷出這樣的參數包。
當函數參數包出現在非推導的上下文中時,永遠不會推導出該參數包的類型。
另外,[temp.arg.explicit] p3指定:
未以其他方式推導出的尾隨模板參數包(14.5.3)將被推導為空的模板參數序列。
因此,將此考慮到f2(1)
調用:包T是一個尾隨模板參數包 (盡管它不是一個尾隨函數參數包 ),因此它推斷為空包並且該調用有效。
但是,對於f1(1)
,包T也不是尾隨模板參數包,因為它后跟U
,因此不會假定每個[temp.arg.explicit] p3為空包。 因此,由於模板參數包T不能推斷出對f1(1)
的調用,所以它不應該參與重載決策,並且調用應該失敗。
請注意,在其他討論中提出了幾個類似的問題/示例,但它們都有微妙的不同:
f(0)
調用是有效的,因為有問題的包是尾隨模板參數包,因此它屬於我上面提到的情況。 以下是CWG 1399的代碼:
template <class... T> void f(T..., int, T...) { } int main() { f(0); // OK f<int>(0,0,0); // OK f(0,0,0); // error }
目前尚不清楚[標准的當前措辭]是否允許以下示例:
template<typename... T> void f(typename T::type...) { } int main() { f<>(); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.