C++ 函数模板参数包不在参数列表的末尾
以下代码编译并运行正常C++ 函数模板参数包不在参数列表的末尾,c++,templates,c++11,variadic-templates,variadic-functions,C++,Templates,C++11,Variadic Templates,Variadic Functions,以下代码编译并运行正常 void foo() { } template <typename T, typename... Args> void foo(T x, Args... args) { cout << x << endl; foo(args...); } // inside main() foo(1,1,1); void foo(){ } 模板 void foo(tx,Args…Args){ cout有趣的是: 问题是参数packArg
void foo() {
}
template <typename T, typename... Args>
void foo(T x, Args... args) {
cout << x << endl;
foo(args...);
}
// inside main()
foo(1,1,1);
void foo(){
}
模板
void foo(tx,Args…Args){
cout有趣的是:
问题是参数packArgs…
出现在T
之前
Args…
是“贪婪的”,因此没有参数留给编译器推断T
,因此它失败
引用标准(强调矿山):
[温度参数]/11
不应遵循功能模板的模板参数包
通过另一个模板参数,除非该模板参数可以
从函数模板的参数类型列表中推导出或具有
默认参数。[示例:
...
// U can 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
。。。
//U既不能从参数类型列表中推导,也不能指定
模板无效f(){}//错误
模板void g(){}//错误
-[结束示例]
(此答案基于)
根据该标准,如果模板参数包用于不在参数列表末尾的功能参数包中,则不可推断该模板参数包
:
当函数参数包出现在非推断上下文中时
([temp.Decrete.type]),该参数包的类型为
例如:
template<class T1, class ... Types> void g1(Types ..., T1);
void h(int x, float& y) {
const int z = x;
g1(x, y, z); // error: Types is not deduced
g1<int, int, int>(x, y, z); // OK, no deduction occurs
}
这是一些额外的信息
[1] 我在标准中找不到关于这一点的直接表达。最接近的一个是,“没有以其他方式推导的后续模板参数包([temp.variadic])将被推导为一个空的模板参数序列。”因此这只是“编译器没有正确实现标准”情况?@MatheusCp,不,标准也不允许这样做。@chris有什么具体原因吗?我不得不投反对票,因为这是错误的。实际上,Args…
不贪婪地使用参数。因为它不在末尾,所以它不使用参数,并且大小将为0
(尚未推导的参数包将返回到零大小)。这意味着T
变为int
,其余两个参数没有用于推导的匹配参数。错误消息“因为候选参数需要1个参数,但提供了3个。”正确无误。但Clang的错误消息不正确。@songyuanyao它在14.8.1p3中。基本上,参数包不能不推断。它们“默认”为空。当然,模板参数包“typename…Args”不是“拖尾”(在我看来,将模板参数包限制为尾随,而不是函数参数包是没有意义的。如果你问我,这是一个奇怪的限制)。其目的是按照描述工作,请参阅和
...
// U can 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
template<class T1, class ... Types> void g1(Types ..., T1);
void h(int x, float& y) {
const int z = x;
g1(x, y, z); // error: Types is not deduced
g1<int, int, int>(x, y, z); // OK, no deduction occurs
}
template <typename T, typename... Args>
void foo(Args... args, T x) {
}
int main() {
// inside main()
foo<int, int, int>(1, 1, 1);
}