c++ - 可变参数模板 initilizer_list 技巧

标签 c++ tuples variadic-templates c++17

我在 visual studio 2017 RC 上使用 C++17 编写了 for_each_tuple,我对这种实现感到震惊。

查看:

template<class fun_t, class tuple_t>
constexpr auto for_each_tuple(fun_t& fun, tuple_t&& tuple) {

    std::apply([&](auto&&... args) {
        auto l = { (fun(std::forward<decltype(args)>(args)), 0)... };
    }, std::forward<tuple_t>(tuple));
}

int main() {
    auto tup = std::make_tuple(
        1, 2, 3, 4
    );
    for_each_tuple([](auto& arg) { ++arg; }, tup);
    for_each_tuple([](auto& arg) {std::cout << arg; }, tup);

}

输出: 2345

我对这部分有严重的疑问:

auto l = { (fun(std::forward<decltype(args)>(args)), 0)... };

这只是编译器技巧还是完全标准的正确方法?

函数调用究竟是如何解析为 std::initilizer_list 的?

您认为如何使该功能更好?

最佳答案

在 C++17 中,这个:

auto l = { (fun(std::forward<decltype(args)>(args)), 0)... }; 

可以重写为:

(fun(std::forward<decltype(args)>(args)), ...);

在等待折叠表达式时,列表技巧是完全合法的(从标准的角度来看)C++11/C++14 解决方法。
基本思想是创建一个列表(或数组),之后立即丢弃。由于逗号运算符的工作方式,该容器中充满了零。最后,参数包的展开只是强制为每个参数调用给定函数。
换句话说,你可以这样想象:

auto l = { (fun(std::forward<decltype(arg0)>(arg0)), 0), (fun(std::forward<decltype(arg1)>(arg1)), 0), (fun(std::forward<decltype(arg2)>(arg2)), 0), and so on... }; 

关于c++ - 可变参数模板 initilizer_list 技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41620877/

相关文章:

c++ - 输出所有可变模板参数

c++ - 可以读/写EEPROM地址但是只能读/写第一个内存页

c++ - 无法获得与 POCO 一起使用的并发 HTTPS 请求

c++ - Rcpp模块 : Manually build/expose C+ classes to R

python - 当默认提供的不是元组时,为什么 python 中的链式字典 .get() 返回元组?

python - 将元组分配给 pandas 中的单元格

c++ - 可变模板类中的模板方法

c++ - 我们能否创建一个类似 scanf 的函数,在填充所有参数时返回 true,否则返回 false,而无需遍历所有变量?

当前一行有多个 "else"语句时,C++ "if"语句

types - 在 Julia 中,为什么在两个元素元组上使用 Pair?