功能模板重载解析,相关和非相关参数 [英] Function template overload resolution, dependent and non-dependent parameters

查看:59
本文介绍了功能模板重载解析,相关和非相关参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下程序

#include <iostream>

template<class T> struct id { using type = T; };

template<class T1, class T2>
int func(T1, T2) { return 0; }

template<class T1, class T2>
int func(typename id<T1>::type, typename id<T2>::type) { return 1; }

int main()
{
    std::cout << func<int, int>(0, 0) << std::endl;
}

GCC和Clang都为该程序打印 1 .是否可以保证该程序按标准打印 1 ?

GCC and Clang both prints 1 for this program. Is this program guaranteed to print 1 by the standard?

我尝试在此处找到答案,但无法解密它.看来功能模板可能是等效的,因此会破坏ODR,但我不确定.

I tried finding the answer here but couldn't decipher it. It looks like the function templates might be equivalent and therefore breaks ODR but I'm not sure.

是否将第二个功能模板更改为

Does changing the second function template to

template<class T>
using id_type = typename id<T>::type;

template<class T1, class T2>
int func(id_type<T1>, id_type<T2>) { return 1; }

有所作为吗?

推荐答案

这是沼泽标准的部分排序.我们将唯一类型替换为功能模板之一,并尝试根据其推论另一种.两种方式都做,如果推论只在一个方向上成功,那么我们就有一个命令.如果要阅读神秘规则,请参阅[临时功能顺序]和[临时扣除部分].

This is bog-standard partial ordering. We substitute unique types into one of the function templates and try to deduce the other against it. Do it both ways and if deduction only succeeds in one direction, we have an order. If you want to read the arcane rules, see [temp.func.order] and [temp.deduct.partial].

所以在这里

  • T1 = U1,T2 = U2 替换为第一个重载的函数类型会产生 int f(U1,U2); 我们可以推导出 T1 T2 在第二次重载中由此而来?不;两者都是在非推论上下文中.嗯,推论失败了.
  • T1 = U1,T2 = U2 替换为第二个重载将产生 int f(id Ult; U1> :: type,id< U2> :: type)(这是在定义上下文中进行的,因此我们不能再将其替换为 id -某处可能会有专门化的内容.我们可以由此得出第一个重载中的 T1 T2 吗?是的,通过推导 T1 = id< U1> :: type T2 = id< U2> :: type .扣除成功.
  • Substituting T1=U1, T2=U2 into the first overload's function type produces int f(U1, U2); Can we deduce T1 and T2 in the second overload from this? No; both are in non-deduced contexts. Ergo, deduction fails.
  • Substituting T1=U1, T2=U2 into the second overload produces int f(id<U1>::type, id<U2>::type) (this is conducted in the definition context so we can't substitute further into id - there may be a specialization somewhere). Can we deduce the T1 and T2 in the first overload from this? Yes, by deducing T1 = id<U1>::type and T2 = id<U2>::type. Deduction succeeds.

由于演绎仅在一个方向上成功-从转换后的第二个演绎中推导-第二个演义比第一个更专业,并且优先由重载解析选择.

Since deduction succeeds only in one direction - deducing the first from transformed second - the second is more specialized than the first and is preferentially picked by overload resolution.

别名模板大小写不变.

这些模板既不等效,也不等效.

These templates are neither equivalent nor functionally equivalent.

这篇关于功能模板重载解析,相关和非相关参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆