【问题标题】:The variadic template with automatic return type argument deduction具有自动返回类型参数推导的可变参数模板
【发布时间】:2021-09-21 21:32:55
【问题描述】:

我实现了将所有数字相加的简单代码,但是当插入一个浮点数时,一切都变得奇怪了!

如何分析编译器的行为来推断返回类型?

#include <iostream>

template <typename N>
auto summer(N n)
{
    return n;
}

template <typename N, typename... Args>
auto summer(N n, Args... args)
{
    return n + summer(args...);
}

int main()
{
    printf("add: %d \n", summer(4, 34.1, 13, 14, 15, 22)); // Print 22 ?!??!? return last number.
    printf("add: %d \n", summer(4, 34.1, 13, 14, 15, 20)); // Print 20 ?!!?!? return last number.
    printf("add: %f \n", summer(4, 34.1, 13, 14, 15, 20)); // It's true 100.1000 ?
}

【问题讨论】:

  • 你可以问编译器:template&lt;typename&gt;int whatis();int tellme = whatis&lt;decltype(summer(4, 34.1, 13, 14, 15, 22))&gt;();。这表示call int whatis&lt;double&gt;(),因此编译器推导出double。这是有道理的,因为4 + (34.1 + (13 + (14 + (15 + 22)))) 的推断类型是double
  • 这就是为什么cout 和朋友比printf 和朋友“更安全”。
  • 我喜欢summer 它是如此的阳光:)。

标签: c++ templates variadic-templates return-type-deduction


【解决方案1】:

问题是summer() 的返回类型是双精度的,但您使用%d 打印它。结果类似于运行这样的代码:

printf("%d", 100.1);

这是 UB(未定义行为)。引用cpp ref:

如果默认转换后的任何参数不是相应转换说明符所期望的类型,或者如果参数少于格式所需的参数,则行为未定义。

【讨论】:

  • @AmirSalar 我说,这种情况是 UB(未定义行为)。你可能会得到任何结果或任何东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-16
  • 1970-01-01
  • 2021-05-23
  • 2018-05-01
  • 1970-01-01
相关资源
最近更新 更多