带有两个参数包的不明确的函数调用

tem*_*boy 9 c++ templates c++11

以下是在clang中编译但不在gcc中编译:

template <class... Ts, class... Args>
void f(Ts&&..., Args&&...);

int main()
{
    f();
}
Run Code Online (Sandbox Code Playgroud)

这是我在GCC中遇到的错误:

main.cpp: In function 'int main()':
main.cpp:30:7: error: no matching function for call to 'f()'
     f();
       ^
main.cpp:30:7: note: candidate is:
main.cpp:23:6: note: template<class ... Ts, class ... Args> void f(Ts&& ..., Args&& ...)
 void f(Ts&&..., Args&&...)
      ^
main.cpp:23:6: note:   template argument deduction/substitution failed:
main.cpp:30:7: note:   candidate expects 1 argument, 0 provided
     f();
       ^
Run Code Online (Sandbox Code Playgroud)

如果我像那样给出一个论点,f(0)它会与GCC编译但不会与Clang编译.

clang错误:

main.cpp:30:5: error: no matching function for call to 'f'
    f(0);
    ^
main.cpp:23:6: note: candidate function not viable: requires 0 arguments, but 1 was provided
void f(Ts&&..., Args&&...)
     ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

如果我给出与函数参数相同数量的显式模板参数,那么它将与两个编译器(即f<int, int, int>(0, 0, 0))进行编译.

Col*_*mbo 2

第二个模板参数包Args确实推导出来了:

未以其他方式推导的尾随模板参数包 (14.5.3) 将被推导为模板参数的空序列。

考虑到这一点,很明显,egf<int>(0)是格式良好的。然而,Ts从未被推论出来。[temp.deduct.call]/1:

当函数参数包出现在非推导上下文 (14.8.2.5) 中时,永远不会推导该参数包的类型

请注意,前面的引用不适用于Ts,因为它不是尾随的。因此,纯粹的演绎总是会失败。