模板重载解析规则

时间:2018-01-04 07:21:35

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

无法理解发生了什么。有没有人可以清楚地解释这些?如果是这样,请给我一些线索或关键词进行搜索。

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 ?
}

如果未定义第2个最大功能,则每个最大呼叫都可以正常工作。在什么地方叫第二个最大值。它的规则是什么?

2 个答案:

答案 0 :(得分:3)

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

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

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

第二种形式是C ++ 11,可能在C ++ 14中提供,以实现向后兼容。另外原则上第二种形式可以控制加宽,但实际上我不确定第二种形式是什么,因为?:必须解析为单一尺寸类型。 [这回答了我认为的补充问题]

例如,如果两种类型都是有符号和无符号的并且返回类型是double(但是你会得到一个警告),那么?:结果可能是unsigned(或错误),然后转换为double,这是无用的。理想情况下,你需要第三个版本来处理签名/未签名的不匹配,如果你关心的话 - 这是一整套特殊情况蠕虫可以彻底解决。

如果它是用2个返回语句编写的,那么它会正确地扩大两半。更好的是,如果在比较之前进行演员阵容......

答案 1 :(得分:1)

max(4, 7.2)从第一个模板生成一个函数,因为已知两个参数<int, double> max<long double>(7.2, 4)从第二个模板生成一个函数,因为已知三个参数(long double, double, int) max<int>(4, 7.2)与以前相同。
max<double, int>(3.4, 2)从第一个模板生成一个函数,因为两个给定的模板参数适合给定的值。这两个参数是<double, int>

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