C++ 模板类和非模板类的可变模板方法行为的令人费解的差异
我正在为一个奇怪的问题抓狂,该问题由以下最小代码突出显示:C++ 模板类和非模板类的可变模板方法行为的令人费解的差异,c++,c++11,C++,C++11,我正在为一个奇怪的问题抓狂,该问题由以下最小代码突出显示: 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> st
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
}
结构A{
模板
无效f(X…a,Y…b){
}
模板
无效g(X…c){
f(c…);
}
};
模板
结构B{
模板
无效f(X…a,Y…b){
}
模板
无效g(X…c){
f(c…);
}
};
int main(){
A A;
a、 g();//编译没有问题
B B;
b、 g();//编译器抱怨说,g()使用0个参数调用f(),而预期为1
}
对于第二种情况,g++和clang++都给出相同的基本错误消息。
他们基本上说,在模板类中调用f()需要一个参数
这是两个编译器中的一个bug,还是我在C++标准中漏掉了什么?
< P>两个参数包的方法是非法的,根据14.1 [ TEMP.PARAM ]第11段: 。。。除非可以从参数类型列表中推断出模板参数,否则功能模板的模板参数包后面不得有另一个模板参数 或具有默认参数(14.8.2)。[示例:模板类B;//错误
//既不能从参数类型列表中推导也不能指定U
模板无效f(){}//错误
模板void g(){}//错误
-[结束示例]
trunk发出的叮当声
在第一个版本中也会出现。很有趣。那么,这种方法或功能在标准中是非法的吗?到目前为止,我从clangg
和gcc
看到的诊断是完全错误的。这似乎是合理的,这是不允许的。@pmr:是的,奇怪的是,Clang在错误中附加了如此奇怪的注意:
s,并且它在未调用f
时编译代码。您显示的示例是可以理解的,但如果U被传递,它可以被推断出来,因此在这种情况下它应该是合法的。但我可以看出我的例子是自找麻烦。听起来编译器也应该抱怨struct A的情况。@Michel:你怎么能传递U
?所有参数都将被T
(以及问题代码中的X
和a
)吞没。@Xeo:template void f(U…{}//从Dietmar所写的参数列表中明确的U,它应该是合法的”,除非该模板参数可以从函数模板的parameter类型列表中推导出来
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