【问题标题】:How to call the idiom of using an array to apply a function to a variadic pack如何调用使用数组将函数应用于可变参数包的习惯用法
【发布时间】:2015-05-07 09:28:28
【问题描述】:

这是有问题的成语:

template<typename... T>
void f(T... t) {
    int temp[] = {(g(t), 0)...};
}

这将被编译为g(t0); g(t1); ...,函数调用的顺序由 C++11[dcl.init.list]/4 保证。
更好的版本使用std::initializer_list而不是数组,但在这里并不重要。

问题是:我们应该如何称呼这个成语?

更新:
基本上,这是我们应该建议人们使用它而不是递归的习语,即替换两个重载
void f() {}
void f(H head, T... tail) { g(head); f(tail...); }
带单
void f(T... t) { int temp[]{(g(t), 0)...}; }

当然我们可以称它为“将被Fold Expressions取代的成语”,但我希望有一个合适的术语。

【问题讨论】:

  • 顺便说一句,在 C++1z 中,这可能会被Fold Expressions取代
  • “包扩展”似乎涵盖了它,是吗?
  • @Cheersandhth.-Alf,谢谢,已修复。不,这不仅仅是“包扩展”——数组的使用在这里起着关键作用。这有点像“this idion vs recursion”
  • 是的,检查过,C++11 标准在 §5.1.2/23 中准确地将此代码称为包扩展。
  • 我可能是盲人,但我在 C++11 §14.5.3/4 中找不到允许在函数调用中进行包扩展的地方(显然是有效的)?

标签: c++ c++11 variadic-templates idioms


【解决方案1】:

包扩展。

[expr.prim.lambda] 中的 C++11 §5.1.2/23:

capture 后跟省略号是包扩展 (14.5.3)。 [例子:

template<class... Args>
void f(Args... args) {
  auto lm = [&, args...] { return g(args...); };
  lm();
}

——结束示例 ]

我认为这涵盖了它。不应用函数的包展开可以看作是应用了恒等函数。

[temp.variadic] 中的 C++11 §14.5.3/4:

pack 扩展由一个模式和一个省略号组成,其实例化产生零个或多个 列表中模式的实例化(如下所述)。 […]

【讨论】:

  • 不,这与 Pack 扩展无关。这就像(不)著名的0 == x 成语与operator== 无关。它是关于如何用大括号初始化器中的包扩展替换递归解包。
  • 那么“使用包扩展”怎么样?
  • 不,不,看 - 使用递归方法,我们也有包扩展 - void f(H h, T... t) { g(h); f(t...); }
  • 这是int tmp[]{(g(t), 0)...}; vs g(h); f(t...);
  • “完整的包扩展”?
【解决方案2】:

也许是“跨参数包扩展的函数调用”?

【讨论】:

  • 好吧,我相信它的名称中应该有“array”,因为例如使用辅助函数 template&lt;class... T&gt; void eat(T...) {} 然后 eat(g(t)...); 也是“跨参数包扩展的函数调用”,但它没有做的事情 - 调用顺序无法保证。
【解决方案3】:

让我们区分折叠和映射。 fold 将一系列输入数据转换为单个值。 map 将一系列输入转换为一系列输出。 (当然,映射可以表示为将一系列标量折叠到单个列表)。

这里我们将所有输入映射到一个空值。 如果我们强调 g(x0)、g(x1) 等的副作用 - 我们可以讨论映射。 如果我们强调产生 void,我们可以谈论纯粹的折叠。但我认为这是没有意义的。

std::transform 是映射。 std::accumulate 正在折叠。什么是 std::for_each?映射还是折叠? (顺便说一句,它是折叠的,因为它返回一个具有累积状态的有状态函数对象)。 至于输入函数是一元的,而不是二元的,它是映射(与折叠融合)。

所以。我想给这个成语“variadic for-each”。

【讨论】:

    猜你喜欢
    • 2011-10-19
    • 2022-07-08
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    相关资源
    最近更新 更多