参数包没有用“...”扩展——gcc 的另一个可变参数模板错误?

Posted

技术标签:

【中文标题】参数包没有用“...”扩展——gcc 的另一个可变参数模板错误?【英文标题】:parameter packs not expanded with ‘...' -- another variadic template bug with gcc? 【发布时间】:2014-03-21 20:13:05 【问题描述】:

众所周知,gcc 对可变参数模板的处理是不完整的(参见例如 this 和 this),但我想知道以下错误是否已知(我在 bugzilla 上找不到)或者是否确实一个错误。本质上,gcc (4.8.1) 无法在 lambda 中扩展参数包:

#include <vector>
#include <algorithm>
#include <type_traits>

template<typename T, typename F, typename... X>
void bar(std::vector<T> const&c, F const&f, X&&... x)

  std:for_each(c.begin(),c.end(),[&](const T&t)
          f(t,std::forward<X>(x)...); );

这会导致(即使没有任何实例化)

error: parameter packs not expanded with ‘...’:
   f(t,std::forward<X>(x)...); );
                        ^

知道如何避免这种情况吗? (注意:icpc 14.0.2 和 clang 3.4 还可以)还是 gcc 是正确的,而 clang 和 icpc 是错误的?

edit 请注意,问题在于 lambda,因为它也无法编译:

template<typename T, typename F, typename... X>
void bar(std::vector<T> const&c, F const&f, X&&... x)

auto func = [&](const T&t) f(t,std::forward<X>(x)...); ;
std:for_each(c.begin(),c.end(),func);

在 lambda 定义中带有“错误”报告。

【问题讨论】:

t传递的第一个参数是什么? @Manu343726 这有什么关系?即使没有实例化也会报告错误。 See it live 随机建议:[&amp;x...] 做什么?或者把它们塞进tuple&lt;X&amp;&amp;...&gt;,然后用std::get&lt;Is&gt;(tup)...取出它们 @Yakk 为什么要[&amp;x...] 提供帮助?我可以尝试元组技巧,但恐怕编译器不会优化它... @walter 只是尝试解决方法:编译器错误。 【参考方案1】:

鉴于 代码可以干净地编译两种 clang 版本 3.5(主干 202594),更重要的是使用 gcc 版本 4.9.0 20140302(实验)(GCC),两者对于-Wall,我会说这是早期版本的 gcc 的问题。

我正在http://gcc.gnu.org/bugzilla/ 寻找 gcc 错误报告来确认这一点。

【讨论】:

老实说:我不知道哪个错误报告可能是相关的。 GCC doesn't expand template parameter pack that appears in a lambda-expression 和 lambdas and variadic templates don't work together 中的代码在 gcc 版本 4.9.0 20140302 中失败,但在 clang 3.5 中通过。我无法确定哪些可能是其他错误报告可能是相关的。 它是41933,因为我尝试将整个包捕获到一个 lambda 中,而不是为包中的每个成员创建另一个 lambda,每个成员都捕获一个。根据 bugzilla 这个是在 4.9 中修复的 @Walter 让我不确定的是:我的 gcc 版本 4.9.0 20140302 中的代码 41933 确实失败,但您的代码没有。失败可能是可以的,因为该错误报告已于 3 月 4 日关闭,即在我检查 gcc 的源代码后 2 天。有可能我检查了一个没有错误修复的版本,因此失败了。那可能没问题。但如果是这样,你的例子也应该失败,但事实并非如此。这就是为什么我很困惑,不确定 41933 是否真的是相关的错误报告。

以上是关于参数包没有用“...”扩展——gcc 的另一个可变参数模板错误?的主要内容,如果未能解决你的问题,请参考以下文章

MSVC++ 可变参数宏扩展

是否可以迭代可变参数宏中的参数?

C++可变参数的另一种实现

可变参数模板错误:“在实例化中”(gcc 9.2)

带有可变参数的嵌套宏在 GCC 中编译,但在 MSVC 中不编译

编译可变参数模板时 GCC 5.3.1 C++ 停止