Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板类和非模板类的可变模板方法行为的令人费解的差异_C++_C++11 - Fatal编程技术网

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