【问题标题】:"Folding" of template parameter packs in pre C++17: idiomatic approachPre C++17 中模板参数包的“折叠”:惯用方法
【发布时间】:2019-10-28 09:51:17
【问题描述】:

C++11 和 C++14 中的折叠表达式:惯用方法?

Q&A Variadic template pack expansionaccepted answer 使用 C++17 之前的通用方法(折叠表达式之前)来“折叠”未扩展的模板参数包。

我已经看到了这种技术的几种不同变体;以上面的问答为例:

#include <initializer_list>
#include <iostream>
#include <utility>

template <typename T> static void bar(T) {}

template <typename... Args> static void foo1(Args &&... args) {
  using expander = int[];
  // Left-most void to avoid `expression result unused [-Wunused-value]`
  (void)expander{0, ((void)bar(std::forward<Args>(args)), 0)...};
}

template <typename... Args> static void foo2(Args &&... args) {
  int dummy[] = {0, ((void)bar(std::forward<Args>(args)), 0)...};
  // To avoid `unused variable 'dummy' [-Wunused-variable]`
  (void)dummy;
}

template <typename... Args> static void foo3(Args &&... args) {
  // Left-most void to avoid `expression result unused [-Wunused-value]`
  (void)std::initializer_list<int>{((void)bar(std::forward<Args>(args)), 0)...};
}

template <typename... Args> static void foo4(Args &&... args) {
  auto l = {0, ((void)bar(std::forward<Args>(args)), 0)...};
  // To avoid `unused variable 'l' [-Wunused-variable]`
  (void)l;
}

int main() {
  foo1(1, 2, 3, "3");
  foo1();
  foo2(1, 2, 3, "3");
  foo2();
  foo3(1, 2, 3, "3");
  foo3();
  foo4(1, 2, 3, "3");
  foo4();
  return 0;
}

这些变体(或其他变体)是否被视为“惯用的变体”?它们之间是否存在任何需要注意的细微差别/差异?

std::initializer_list 方法不需要 braced-init-list 中有些难以捉摸的最左侧 0,因为初始化列表可能为空,而数组可能不为零(/负)大小。可能这可能是 foo3 的一个论据(可以说复杂性略低,但需要额外的 #include)。

【问题讨论】:

  • 是否保证所有变体的执行顺序? (我想是为了foo3,得寻找我的信仰来源。)
  • @generic_opto_guy 所有变体都使用 braced-init-list 条目,条目由逗号运算符分隔;前者保证按出现顺序进行评估([dcl.init.list]),后者从左到右评估([expr.comma]),所以我相信执行顺序是有保证的(并且相同)所有变体。

标签: c++ templates c++14 variadic-templates


【解决方案1】:

这些变体(或其他变体)是否被视为“惯用的变体”?

我会说是的。

它们之间是否有任何需要注意的细微差别/差异?

大部分是等价的,但是

foo3foo4 需要 #include &lt;initializer_list&gt;
foo1foo2 则不然。

【讨论】:

  • 感谢您的回答。另一方面,std::initializer_list 方法不需要 braced-init-list 中有些难以捉摸的最左侧 0 值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 2016-10-27
相关资源
最近更新 更多