2012-12-06 42 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