【问题标题】:Unpacking parameter packs in template aliases在模板别名中解包参数包
【发布时间】:2014-08-17 11:47:44
【问题描述】:

我在将可变参数模板解压缩为模板别名时遇到了问题。

以下代码适用于 Clang 3.4 和 GCC 4.8,但适用于 GCC 4.9:

template <typename T, typename...>
using front_type = T;

template <typename... Ts>
struct foo
{
  using front = front_type<Ts...>;
};

GCC 4.9 抱怨:

test.cc:7:37: error: pack expansion argument for non-pack parameter 'T' of alias template 'template<class T, class ...> using front_type = T'
       using front = front_type<Ts...>;
                                     ^
test.cc:1:15: note: declared here
     template <typename T, typename...>
               ^

存在已提交的 GCC 错误 (#59498),但这应该会失败吗?以下是来自C++ core language issue #1430, "pack expansion into fixed alias template parameter list" 的一些上下文:

最初,包扩展无法扩展为固定长度的模板参数列表,但在 N2555 中进行了更改。这适用于大多数模板,但会导致别名模板出现问题。

在大多数情况下,别名模板是透明的;当它在模板中使用时,我们可以替换依赖的模板参数。但是,如果模板 ID 对非可变参数使用包扩展,这将不起作用。例如:

  template<class T, class U, class V>
  struct S {};

  template<class T, class V>
  using A = S<T, int, V>;

  template<class... Ts>
  void foo(A<Ts...>);

没有办法用S来表达A&lt;Ts...&gt;,所以我们需要保持A直到我们有Ts可以替换,因此需要在mangling中处理.

目前,EDG 和 Clang 拒绝了这个测试用例,抱怨 A 的模板参数太少。G++ 也这样做了,但我认为这是一个错误。然而,在 ABI 列表中,John Spicer 认为它应该被拒绝。

【问题讨论】:

  • 你能把 front_type 移到 foo 之外吗?它们似乎不相关?
  • 是的,好点@PiotrNycz。 (但它并没有解决它。)
  • 我用 gcc4.8 检查了这个修改后的代码 - 看起来它可以工作。
  • "works with Clang 3.4" 然而,这被 clang 3.5.0 拒绝了:error: pack expansion used as argument for non-pack parameter of alias template

标签: c++ c++11 variadic-templates gcc4.9 template-aliases


【解决方案1】:

在 gcc4.9 bugzilla 中报告:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59498

最少的代码重现

template <typename T, typename ...>
using alias = T;

template <typename ...T>
using variadic_alias = alias<T...>;

using Fail = variadic_alias<int>;

int main() { }

根据 gcc 人员的解释 - 这不是很明显这是一个真正的错误。 这仍然是在 gcc bugzilla 和 DR 1430 (http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430) 中进行的讨论 - 现在在上面的问题中进行总结。

【讨论】:

  • 它被报告为一个错误,但看看 cmets 这似乎是设计使然。
  • 是的,看起来这应该失败?我用#1430的上下文编辑了这个问题
  • @MatthiasVallentin 我错过了您的评论 - 我将从我的答案中删除重复的内容。
猜你喜欢
  • 2018-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 2015-08-22
相关资源
最近更新 更多