Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.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++_Templates_C++11_Variadic Templates_Variadic Functions - Fatal编程技术网

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有趣的是:

问题是参数pack
Args…
出现在
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);
}