模板中的类型转换

时间:2018-10-26 17:08:29

标签: c++ c++11 templates type-conversion type-deduction

我正在使用模板化函数和非模板化函数。代码在下面给出

#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,但是谁能解释为什么在第二个函数中也没有发生?第二个功能也只有模板具有相同的功能。

2 个答案:

答案 0 :(得分:2)

扣除冲突。

给出

WHERE

如果您呼叫<?php $link = mysqli_connect("localhost","root","root","test"); if(isset($_POST['logg'])){ $login = $_POST['login']; $pasw = $_POST['password']; if(empty($_POST['login'])||empty($_POST['password'])){ echo '<script language="javascript">'; echo 'alert("Lracnel dashty")'; echo '</script>'; } else { // Don't forget to sanitize your input before the query $sql = "SELECT login, password FROM contact_form WHERE login = $login "; $result = mysqli_query($link,$sql); while ($lol = mysqli_fetch_assoc($result)) { if($login==$lol['login']){ if(password_verify($pasw, $lol['password'])){ echo 'Welcome '.$lol['login']; } else{ echo 'Wrong password'; } } else{ echo 'Wrong login'; break; } } } } ?> ,则第一个值为template<class T> T maxOfTwo(T a,T b) { return a>b?a:b; } ;第二个是maxOfTwo(3,6.3)

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

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

如果至少可以使用C ++ 14,则可以使用两种模板类型和返回的float类型来解决

int

在C ++ 11中,有些冗长但不太优雅

auto

或者您可以使用template <typename T1, typename T2> auto maxOfTwo (T1 a, T2 b) { return a>b?a:b; } (由Yakk建议)

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

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

std::common_type

答案 1 :(得分:1)

在第一种情况下,参数的类型是已知的( int ),参数将转换为格式良好的类型( int )。 / p>

在第二种情况下,编译器必须推断出 T ,但是它的推论结果相互矛盾,因此会失败。

我们可以从[temp.deduct.type]p2中看到这一点,它说(强调我):

  

在某些情况下,推导是使用一组类型的P和A完成的,在其他情况下,将存在一组对应的类型P和A。类型推导是对每个P / A对独立进行的,并且然后将推导的模板参数值组合在一起。如果无法对任何P / A对进行类型推导,或者如果对任何一对推导导致一组以上的推论值,或者或者不同对产生不同的推论值,或者模板参数既不推导也未明确指定,模板参数推导失败。

P A 的定义可以在[temp.deduct.call]p1中找到:

  

模板自变量推导是通过将每个函数模板参数类型(称为P)与调用的相应参数(称为A)的类型进行比较来完成的,如下所述。如果从P删除引用和cv限定词给出了某些P'的std :: initializer_list,并且参数是一个初始化列表([dcl.init.list]),则对初始化列表的每个元素执行推导,取P '作为函数模板参数类型,并使用初始化程序元素作为其参数。否则,使用初始化列表参数将参数视为非推导上下文([temp.deduct.type])。

max66提供了一些可能的解决方案,即结合使用不同的模板参数和common_type