問題描述
我想知道為什么下面的代碼不能編譯:
I am wondering why the following code doesn't compile:
struct S
{
template <typename... T>
S(T..., int);
};
S c{0, 0};
此代碼無法同時使用 clang 和 GCC 4.8 進行編譯.這是 clang 的錯誤:
This code fails to compile with both clang and GCC 4.8. Here is the error with clang:
test.cpp:7:3: error: no matching constructor for initialization of 'S'
S c{0, 0};
^~~~~~~
test.cpp:4:5: note: candidate constructor not viable: requires 1 argument, but 2 were provided
S(T..., int);
^
在我看來這應該可行,并且 T 應該被推導出為長度為 1 的包.
It seems to me that this should work, and T should be deduced to be a pack of length 1.
如果標準禁止做這樣的事情,有誰知道為什么?
If the standards forbids doing things like this, does anyone know why?
推薦答案
因為當一個函數(shù)形參包不是最后一個形參時,那么模板形參包就不能從中推導出來,模板實參推導會忽略它.
Because when a function parameter pack is not the last parameter, then the template parameter pack cannot be deduced from it and it will be ignored by template argument deduction.
因此將兩個參數(shù) 0, 0
與 , int
進行比較,結果不匹配.
So the two arguments 0, 0
are compared against , int
, yielding a mismatch.
這樣的推導規(guī)則需要涵蓋很多特殊情況(比如兩個參數(shù)包并排出現(xiàn)時會發(fā)生什么).由于參數(shù)包是 C++11 中的一個新特性,相應提案的作者在起草規(guī)則時比較保守.
Deduction rules like this need to cover many special cases (like what happens when two parameter packs appear next to each other). Since parameter packs are a new feature in C++11, the authors of the respective proposal drafted the rules conservatively.
請注意,如果沒有以其他方式推導出,尾隨模板參數(shù)包將為空.所以當你用一個參數(shù)調用構造函數(shù)時,事情就會起作用(注意這里模板參數(shù)包和函數(shù)參數(shù)包的區(qū)別.前者是拖尾的,后者不是).
Note that a trailing template parameter pack will be empty if it is not otherwise deduced. So when you call the constructor with one argument, things will work (notice the difference of template parameter pack and function parameter pack here. The former is trailing, the latter is not).
這篇關于帶有包擴展的可變函數(shù)模板不在最后一個參數(shù)中的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!