我在 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::initializer_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... };
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)