[英]“Folding” of template parameter packs in pre C++17: idiomatic approach
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
為代價稍微降低了復雜性)。
這些變體(或其他變體)是否被視為“慣用的變體”?
我會說是的。
它們之間是否存在任何需要注意的細微差別/差異?
大部分是等效的,但是
foo3
和foo4
需要#include <initializer_list>
而foo1
和foo2
沒有。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.