簡體   English   中英

C++17 之前模板參數包的“折疊”:慣用方法

[英]“Folding” of template parameter packs in pre C++17: idiomatic approach

C++11 和 C++14 中的折疊表達式:慣用方法?

Q&A Variadic 模板包擴展公認答案使用 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方法不需要花括號初始化列表中有些難以捉摸的最左邊的0 ,因為初始化列表可能為空,而數組可能不是零(/負)大小。 可能這可能是foo3的一個論點(可以說,以額外的#include為代價稍微降低了復雜性)。

這些變體(或其他變體)是否被視為“慣用的變體”?

我會說是的。

它們之間是否存在任何需要注意的細微差別/差異?

大部分是等效的,但是

foo3foo4需要#include <initializer_list>
foo1foo2沒有。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM