gpt4 book ai didi

c++ - 使用可变参数模板进行扩展

转载 作者:IT老高 更新时间:2023-10-28 12:33:05 24 4
gpt4 key购买 nike

gun函数的以下3个调用有什么区别?

template <class... Ts> void fun(Ts... vs) {
gun(A<Ts...>::hun(vs)...);
gun(A<Ts...>::hun(vs...));
gun(A<Ts>::hun(vs)...);
}

我对使用特定示例解释这三个调用的答案感兴趣。

最佳答案

最初我只是从字面上回答了这个问题,但我想稍微扩展一下,以便更彻底地解释什么包是如何扩展成什么的。无论如何,这就是我思考事情的方式。

任何紧跟省略号的包都会在原地展开。所以A<Ts...>相当于 A<T1, T2, ..., TN>hun(vs...)类似地等价于 hun(v1, v2, ..., vn) .它变得复杂的地方是当你得到类似 ((expr)...) 的东西时,而不是一个包后跟省略号。 .这将扩展为 (expr1, expr2, ..., exprN)在哪里 expri指原始表达式,任何包替换为 i它的第一个版本。所以如果你有 hun((vs+1)...) , 变成 hun(v1+1, v2+1, ..., vn+1) .更有趣的地方是expr可以包含多个包装(只要它们的尺寸相同!)。这就是我们实现标准完美转发模型的方式;

foo(std::forward<Args>(args)...)

这里 expr包含两个包(Argsargs 都是包)并且扩展“迭代”两个包:

foo(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), ..., std::forward<ArgN>(argN));

这种推理应该可以让您快速浏览您的案例,例如,当您调用 foo(1, 2, '3') 时会发生什么.

第一个,gun(A<Ts...>::hun(vs)...);展开 Ts “就地”,然后有一个表达式可以扩展最后一个省略号,因此调用:

gun(A<int, int, char>::hun(1), 
A<int, int, char>::hun(2),
A<int, int, char>::hun('3'));

第二个,gun(A<Ts...>::hun(vs...));展开两个包:

gun(A<int, int, char>::hun(1, 2, '3'));

第三个,gun(A<Ts>::hun(vs)...) , 同时展开两个包:

gun(A<int>::hun(1), 
A<int>::hun(2),
A<char>::hun('3'));

[更新] 为完整起见,gun(A<Ts>::hun(vs...)...)会打电话:

gun(A<int>::hun(1, 2, '3'),
A<int>::hun(1, 2, '3'),
A<char>::hun(1, 2, '3'));

最后,还有最后一种情况需要考虑,我们在椭圆上的位置过分了:

gun(A<Ts...>::hun(vs...)...);

这不会编译。我们同时扩展 Tsvs “到位”,但是我们没有任何包可以扩展最终的椭圆。

关于c++ - 使用可变参数模板进行扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26767127/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com