【问题标题】:Ambiguous function call with two parameter packs带有两个参数包的模棱两可的函数调用
【发布时间】:2015-03-16 09:11:29
【问题描述】:

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

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

int main()
{
    f();
}

这是我在 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();
       ^

如果我给出像 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.

如果我提供与函数参数相同数量的显式模板参数,那么它可以使用两个编译器进行编译(即f&lt;int, int, int&gt;(0, 0, 0))。

【问题讨论】:

  • 我不明白这应该如何工作。如果你打电话给f(1, 2, 3, 4) 甚至f&lt;int, int, int, int&gt;(1, 2, 3, 4) - 哪些是Ts 哪些是Args?编译器如何知道前者的结束位置和后者的开始位置?是二加二、一加三、零加四吗?
  • @IgorTandetnik 我没想到他们中的任何一个都能工作。
  • 向每个人提交错误报告“accepts-invalid”。
  • 看来您甚至可以添加更多参数包并获得相同的行为...

标签: c++ templates c++11


【解决方案1】:

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

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

考虑到这一点,例如f&lt;int&gt;(0) 格式正确。然而,Ts 从未被推断出来。 [temp.deduct.call]/1:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-09
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多