模板中的类型转换

Type conversion in template

本文关键字:类型转换      更新时间:2023-10-16

我使用的是模板化函数和非模板化函数。下方给出了代码

#include <iostream>
using namespace std;
int maxOfTwo1(int a,int b)
{
return a>b?a:b;
}
template<class T>
T maxOfTwo(T a,T b)
{
return a>b?a:b;
}
int main()
{
cout<<maxOfTwo1(3,6.3);//works fine
cout<<maxOfTwo(3,6.3);//gives error
}

在第一个函数中,6.3被转换为6,但有人能解释为什么它没有在第二个函数中发生吗?第二个函数也同样工作,只是有模板。

演绎冲突。

给定

template<class T>
T maxOfTwo(T a,T b)
{
return a>b?a:b;
}

如果调用maxOfTwo(3,6.3),则第一个值为int;第二个是CCD_ 5。

编译器必须推导出单个T类型,并且不知道是选择int还是float

maxOfTwo1()的情况不同,因为参数类型固定为int,编译器只需将float值转换为int值。

如果你至少可以使用C++14,你可以使用两种模板类型和一个返回的auto类型来解决问题

template <typename T1, typename T2>
auto maxOfTwo (T1 a, T2 b)
{ return a>b?a:b; }

在C++11中,有点冗长而不那么优雅

template <typename T1, typename T2>
auto maxOfTwo (T1 a, T2 b) -> decltype( a>b ? a : b )
{ return a>b?a:b; }

或者您可以使用std::common_type(如Yakk所建议的(

template <typename T1, typename T2>
typename std::common_type<T1, T2>::type maxOfTwo (T1 a, T2 b)
{ return a>b?a:b; }

否则,您可以显式调用函数的正确类型

maxOfTwo<int>(3, 6.3);

在第一种情况下,参数的类型是已知的(int(,并且参数被转换为该类型(

int在第二种情况下,编译器必须推导T,但它以冲突的推导结束,因此失败。

我们可以从[temp.dexect.type]p2中看到这一点,p2上写着(强调我的(:

在某些情况下,推导是使用一组类型p和a完成的,在其他情况下,将有一组相应的类型p和a.类型推导是为每个p/a对独立完成的,然后将推导出的模板参数值组合起来。如果无法对任何P/A对进行类型推导,或者如果对任何一对的推导导致多个可能的推导值集,或者如果不同的对产生不同的推导值,或者如果任何模板参数既没有推导也没有显式指定,则模板参数推导失败

pA的定义可以在[temp.decure.call]p1:中找到

模板参数推导是通过将每个函数模板参数类型(称为p(与调用的相应参数类型(也称为A(进行比较来完成的,如下所述。如果从P中删除引用和cv限定符会为某些P'提供std::initializer_list,并且参数是初始值设定项列表([dcl.init.list](,则会对初始值设定值列表的每个元素执行推导,将P'作为函数模板参数类型,将初始值设定器元素作为其参数。否则,初始值设定项列表参数会导致该参数被视为非推导上下文([temp.execure.type](

max66给出了一些可能的解决方案,即使用不同的模板参数与common_type相结合。