【问题标题】:Auto return type of template and ambiguity模板的自动返回类型和歧义
【发布时间】:2020-05-02 06:10:37
【问题描述】:

我有一个重载的模板函数:

template<typename T1, typename T2>
auto overMax(T1 a, T2 b)
{
    std::cout << __FUNCSIG__ << std::endl;

    return b < a ? a : b;
}

template<typename RT, typename T1, typename T2>
RT overMax(T1 a, T2 b)
{
    std::cout << __FUNCSIG__ << std::endl;

    return b < a ? a : b;
}

如果我这样称呼它:

auto a = overMax(4, 7.2); // uses first template
auto b = overMax<double>(4, 7.2); // uses second template

一切都很完美,但是

auto c = overMax<int>(4, 7.2); // error

导致模棱两可的调用。

int为什么会这样,还有哪些其他类型呢?

【问题讨论】:

  • 我认为.........编译器看到它的方式是:使用int,您是指定typename RT 还是typename T1?因为4 也是int,它也可以是。对于double4直接匹配类型double,因此首选第二个重载。
  • 这对我来说看起来有点狡猾,因为您在返回类型上有点重载,但模板具有不同数量的参数。

标签: c++ templates c++17 visual-studio-2019 template-argument-deduction


【解决方案1】:

RT是不可推演的,所以不提供时,只能调用template<typename T1, typename T2> auto overMax(T1 a, T2 b)

当您(部分)提供一个模板参数时,这两种方法都是可行的,

但根据论点,一个人可能是更好的候选人:

  • 对于auto b = overMax&lt;double&gt;(4, 7.2); // uses second template

    overMax&lt;double, int, double&gt;overMax&lt;double, double&gt; 都是可行的。
    但是overMax&lt;double, int, double&gt; 完全匹配
    overMax&lt;double, double&gt; 需要intdouble 的转换。

  • 对于auto c = overMax&lt;int&gt;(4, 7.2); // Ambiguous call

    overMax&lt;int, int, double&gt;overMax&lt;int, double&gt; 都是可行的。
    但两者都不是更好的匹配或更专业,所以这个调用是模棱两可的。

【讨论】:

  • 为什么两者都不是更好?我对吗,在第一种情况下 overMax(4, 7.2); 会导致 7.2 转换为 int。而在第二种情况下,最初为 double 的返回结果将由于显式 被转换为 int ?
  • @amplifier: overMax&lt;int&gt;(4, 7.2) 在第一种情况下是T1=int(提供),T2=double(推导),在第二种情况下是RT=int(提供),T1=int, T2=double(推导)。两种方法的内容定义不用于选择重载。
  • 对我来说,第二种情况是合适的,因为第一种有返回类型转换,第二种根本没有转换,不是吗?
  • hmmm...返回类型转换不起作用...那么,是的,从这个角度来看,两个调用都是等效的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-09
  • 2019-02-26
  • 2018-02-21
  • 1970-01-01
  • 2021-02-14
相关资源
最近更新 更多