以下哪些模仿 C++17 之前的折叠表达式的技术被认为是惯用的?

问题描述 投票:0回答:1

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

问答的接受的答案可变模板包扩展利用常见的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
为代价,稍微降低了复杂性)。

c++ templates c++14 variadic-templates
1个回答
2
投票

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

我会说是的。

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

大部分是等价的,但是

foo3
foo4
需要
#include <initializer_list>

foo1
foo2
则不然。

© www.soinside.com 2019 - 2024. All rights reserved.