递归可变参数模板是如何工作的?

huangapple go评论117阅读模式
英文:

How recursive variadic templates is work?

问题

为什么 count 等于 1?我预期 count 应该是 8sum 模板函数只被调用了一次吗?

不好意思,我只能回答您提出的翻译请求。如果您有其他问题,可以提出并请求翻译。

英文:

With this code:

  1. static unsigned count = 0;
  2. template<typename... T>
  3. auto sum(T... args)
  4. {
  5. ++count;
  6. return (... + args);
  7. }
  8. int main (void)
  9. {
  10. std::cout << sum(12, 32, 32, 12, 4, 3, 43, 432) << std::endl;
  11. std::cout << "TIME: " << count << std::endl;
  12. }

Output is:

  1. $> ./program.out
  2. 570
  3. TIME: 1

Why is count equals to 1? I expected count to be 8. Is sum template function called only once?

答案1

得分: 2

是的,它不会被递归调用。相反,该表达式会为折叠表达式展开。

折叠表达式的实例化将表达式e展开如下:

...
2) 一元左折叠*(... op E)* 变为 (((E1 op E2) op ...) op EN)
...

(其中N是包扩展中元素的数量)

您可以将++count放入折叠表达式中,例如:

  1. template<typename... T>
  2. auto sum(T... args)
  3. {
  4. return (... + (++count, args));
  5. }

正如@Xatyrian所指出的,它的值与包扩展中元素的数量相同,也可以通过sizeof...获取。

英文:

> Is sum template function call once ?

Yes, it won't be called recursively. Instead, the expression is expanded for fold expression.

> The instantiation of a fold expression expands the expression e as
> follows:
>
> ...
> 2) Unary left fold (... op E) becomes (((E<sub>1</sub> op
> E<sub>2</sub>) op ...) op E<sub>N</sub>)

> ...
>
> (where N is the number of elements in the pack expansion)

You might want to put ++count into the fold expression, e.g.

  1. template&lt;typename... T&gt;
  2. auto sum(T... args)
  3. {
  4. return (... + (++count, args));
  5. }

As @Xatyrian pointed, its value is just same as the number of elements in the pack expansion, which could be taken by sizeof... too.

答案2

得分: 0

如果您想多次调用sum函数,您可以使用递归方式实现:

  1. static unsigned count = 0;
  2. template <typename T>
  3. auto sum(T t)
  4. {
  5. ++count;
  6. return t;
  7. }
  8. template <typename T, typename... Ts>
  9. auto sum(T t, Ts... ts)
  10. {
  11. ++count;
  12. return t + sum(ts...);
  13. }
英文:

If you wanted to call sum multiple times, you could do so recursively:

  1. static unsigned count = 0;
  2. template &lt;typename T&gt;
  3. auto sum(T t)
  4. {
  5. ++count;
  6. return t;
  7. }
  8. template &lt;typename T, typename... Ts&gt;
  9. auto sum(T t, Ts... ts)
  10. {
  11. ++count;
  12. return t + sum(ts...);
  13. }

huangapple
  • 本文由 发表于 2020年1月3日 16:59:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/59575635.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定