2017-01-14 170 views
1

當我想將可變參數模板參數包分爲兩部分時,我遇到了這個問題,第一部分包含除最後一部分以外的所有元素,第二部分僅包含最後一部分。一個簡單的實現,它來到我的腦海,在下面的例子中invoke1功能:Variadic模板類型扣除

template <typename... Ts> 
void invoke1(Ts... ts, int param) { 
} 

template <typename... Ts> 
void invoke2(int param, Ts... ts) { 
} 

int main() {  
    invoke1(1); // this works 
    invoke2(1); // this works 

    invoke1(1, 2, 3); // this does not work 
    invoke1<int, int>(1, 2, 3); // this works 
    invoke2(1, 2, 3); // this works 

    return 0; 
} 

爲什麼當第一次指定的模板參數包模板參數不推導出invoke1?類型扣除會產生歧義嗎?

回答

2
template <typename... Ts> 
void invoke1(Ts... ts, int param) { 
} 

首先,爲什麼

invoke1<int, int>(1, 2, 3); 

工作?上面明確指定了類型,所以不需要類型扣除。該模板實例化爲:

void invoke1(int, int, int); 

因此與(1, 2, 3)的呼叫現在變得完全有效。

另一方面,如果不明確指定類型,編譯器無法知道參數包的結束位置。 它是invoke1(int, int, int, int);invoke1(int, int, int);

現在,你會說:「不能只取最後一個給定的參數,並在它之前結束參數包?」。那麼,答案是沒有

invoke2另一方面工作正常,因爲它清楚參數包開始和結束的位置。作爲一個經驗法則,總是把參數包放在最後。

+0

>現在,你會說:「不能只取最後一個給定的參數,並在它之前結束參數包?」。那麼,答案是否定的。 爲什麼不回答?這是我的主要問題。 – Jodebo

+0

@Jodebo因爲這是功能如何指定和標準化。 – DeiDei

+0

但恕我直言標準很多事情是由那它就可以工作「的方式。我的問題是,爲什麼編譯器不能推斷模板參數?什麼是反對它的原因?它會在類型扣除等方面造成含糊之處嗎?還是僅僅是語言缺陷,沒有人提交論文? – Jodebo