给定非可变函数模板:
template<class T>
void f(void(t)(T));
还有一些简单的功能:
void f1(int);
void f2(char);
这有效:
f(f1);
t
的类型变为void (*)(int)
。
然而,可变对应物:
template<class... T>
void f(void(...t)(T));
// call
f(f1, f2);
不起作用。编译器(gcc&amp; clang)抱怨不匹配的类型void(T)
和void (*)(int)
。请参阅DEMO。
请注意,如果明确添加*
,则可以正常使用:
template<class... T>
void f(void(*...t)(T));
那么,为什么非可变参数可以衰减函数类型而可变参数不能?
答案 0 :(得分:3)
AFAICS,代码很好(同样由VC++和ICC编译它的事实支持)。毕竟,模板参数推导似乎与函数类型一样,就像它对函数指针或引用类型一样; [temp.deduct.type]/18:
template-argument 可以从函数类型中推断出来。
对于出现在 parameter-declaration-list 末尾的函数参数包, 对于调用的每个剩余参数执行推导,获取 declarator-id 的类型
P
函数参数包作为相应的函数模板参数类型。每个扣除推断 由函数扩展的模板参数包中后续位置的模板参数 参数包。
特别是后一段确认存在一些不一致性,因为在第二种情况下({1}}包的(不成功)扣除减少到案例1中的(成功)扣除。
我的猜测是Clang和GCC在声明时就拒绝了函数模板的参数类型,但是当参数是包扩展(然后无法推断)时拒绝这样做。当我们将样本调用改为T
时,Clang的错误消息是
注意:候选模板已被忽略:无法将
匹配f(f1)
与'void (T)'
所以这个论点实际上是在扣除之前就已经腐朽了。
答案 1 :(得分:0)
因为你的语法不太正确。
template<class... T>
void f(void(t)(T...));
void f1(int);
void foo()
{
f(f1);
}
使用gcc 6.1.1测试。编译没有错误。
在非变量版本中,您使用模板参数作为传递函数参数的参数的参数。
因此,对于可变参数版本,参数包扩展的位置。
答案 2 :(得分:0)
这解释了吗?
var a = 0;
var b = 0;
var z = 0;
var x = 0;
function findOutlier(integers){
//your code here
while(x < integers.length){
if(integers[x]%2 === 0){
a = x;
z = z + 1;
}
else{
b = x;
}
x = x + 1
}
if(z === 1){return integers[a]}
else{return integers[b]}
}
findOutlier([2,6,8,10,3]);