2012-12-06 79 views
9
可變參數模板法行爲的區別

我抓我的頭被以下最少的代碼高亮一個奇怪的問題:令人費解的模板和非模板類

struct A { 
    template <typename ...X, typename ...Y> 
    void f(X... a, Y...b) { 
    } 

    template <typename ...X> 
    void g(X...c) { 
     f<X...> (c...); 
    } 
}; 

template <typename T> 
struct B { 
    template <typename ...X, typename ...Y> 
    void f(X... a, Y...b) { 
    } 

    template <typename ...X> 
    void g(X...c) { 
     f<X...> (c...); 
    } 
}; 



int main() { 
    A a; 
    a.g(); // Compiles without problem 

    B<int> b; 
    b.g(); // Compiler complains saying g() calls f<>() with 0 arguments while 1 is expected 
} 

兩個g ++以及鐺++給出了相同的基本錯誤信息第二種情況。 他們基本上說在模板類中調用f()需要一個參數。

這是兩個編譯器的錯誤,還是我錯過了C++標準中的某些東西?

+0

'從主幹clang'也borks上的第一個版本。 – pmr

+0

有趣。那麼標準中的這種方法或功能是不合法的? – Michel

回答

6

以兩個參數組的方法,根據14.1是非法[temp.param]段落11:

...函數模板的模板參數包不應被隨後另一模板參數,除非該模板參數可以從函數模板的參數類型列表 中推導出來,或者具有默認參數(14.8.2)。 [實施例:

template<class T1 = int, class T2> class B; // error 
// U cannot be neither deduced from the parameter-type-list nor specified 
template<class... T, class... U> void f() { } // error 
template<class... T, class U> void g() { } // error 

末端示例]

+0

到目前爲止,我從「clang」和「gcc」中看到的診斷是完全錯誤的。這是不允許的,這似乎是合理的。 – pmr

+0

@pmr:是的,Clang有這麼奇怪的'note:'附加到錯誤,並且它在所有未調用'f'時編譯代碼是很奇怪的。 – Xeo

+0

你展示的例子是可以理解的,但如果U通過了,它可以被推斷出來,所以在這種情況下它應該是合法的。但我可以看到,我的榜樣正在尋求麻煩。 聽起來像編譯器也應該抱怨結構A的情況。 – Michel