【问题标题】:template overloading resolution rules模板重载解析规则
【发布时间】:2018-01-04 07:21:35
【问题描述】:

只是无法理解发生了什么。有谁能把这些解释清楚吗?如果有,请给我一些线索或关键字搜索。

template <typename T1, typename T2>
auto max (T1 a, T2 b) {
  std::cout << "1" << std::endl;
  return a > b ? a : b;
}

template <typename RT, typename T1, typename T2>
RT max (T1 a, T2 b) {
  std::cout << "2" << std::endl;
  return a > b ? a : b;
}

void func() {
  auto a = max(4, 7.2); // 1 ? 
  auto b = max<long double>(7.2, 4); // 2 ?
  auto c = max<int>(3.4, 2); // 2 ?
  auto e = max<double, int>(3.4, 2); // 1 ?
}

如果未定义第二个 max 函数,则每个 max 调用都可以正常工作。在什么地方调用第二个最大值。它的规则是什么?

【问题讨论】:

  • 可能对你们来说很明显。没有构建问题。我只是不明白如何决定在每个 max 调用中调用哪个函数。
  • 请给我一些线索或关键字搜索。你要找的关键字可能是模板类型推导
  • @DeanSeo 谢谢

标签: c++ templates c++14 overloading


【解决方案1】:

如果不指定模板类型,则永远不会使用第二种形式,因为 RT 无法推导,必须指定。

如果您确实指定了一个类型,并且它与从参数推导出的 T1 不同,则使用第二种形式。

请注意,第一种形式实际上是 C++14,而不是 C++11。在 C++11 中,您必须以一种或另一种方式指定返回类型。

第二种形式是 C++11,为了向后兼容,可能会在 C++14 中提供。同样原则上,第二种形式可以让您控制扩大,但实际上我不确定第二种形式会给您带来什么,因为 ?: 必须解析为单一尺寸类型。 [我认为这回答了你的补充问题]

例如,如果这两种类型是有符号和无符号的,并且返回类型是双精度(但您会收到警告),那么 ?: 结果可能是无符号的(或错误),然后强制转换为双精度,这是没有帮助的.理想情况下,您需要第三个版本来处理有符号/无符号不匹配,如果您关心的话 - 这是一整罐特殊情况的蠕虫,可以彻底解决。

如果它是用 2 个 return 语句写成的,那么它会正确地加宽两半。更好的是,如果在比较之前进行演员表...

【讨论】:

    【解决方案2】:

    max(4, 7.2) 从第一个模板生成一个函数,因为两个参数 &lt;int, double&gt; 是已知的。
    max&lt;long double&gt;(7.2, 4) 从第二个模板生成一个函数,因为三个参数 (long double, double, int) 是已知的。
    max&lt;int&gt;(4, 7.2) 是和以前一样。
    max&lt;double, int&gt;(3.4, 2) 从第一个模板生成一个函数,因为两个给定的模板参数适合给定的值。两个参数是&lt;double, int&gt;

    如果没有给出模板参数,编译器会尝试从函数调用中推断出类型。

    【讨论】:

    • 我认为auto的推演规则也很相关,在这种情况下,值得一提。
    • 我认为auto返回类型不会改变模板推导。您可以将其更改为某种具体类型。在本例中用于更改模板类型的数量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多