Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 不带<;调用模板函数>;;类型推断_C++_Templates_Types_Inference - Fatal编程技术网

C++ 不带<;调用模板函数>;;类型推断

C++ 不带<;调用模板函数>;;类型推断,c++,templates,types,inference,C++,Templates,Types,Inference,如果我有一个带有typename T的函数模板,其中编译器可以自己设置类型,那么我在调用函数时不必显式地编写类型,如: template < typename T > T min( T v1, T v2 ) { return ( v1 < v2 ) ? v1: v2; } int i1 = 1, i2 = 2; int i3 = min( i1, i2 ); //no explicit <type> 模板 最小温度(T v1,T v2){ 返回(v1 L

如果我有一个带有
typename T
的函数模板,其中编译器可以自己设置类型,那么我在调用函数时不必显式地编写类型,如:

template < typename T > 
T min( T v1, T v2 ) {
   return ( v1 < v2 ) ? v1: v2;
}
int i1 = 1, i2 = 2; int i3 = min( i1, i2 ); //no explicit <type> 
模板
最小温度(T v1,T v2){
返回(v1
但是如果我有一个具有两个不同类型名称的函数模板,比如:

template < typename TOut, typename TIn >
TOut round( TIn v ) {
   return (TOut)( v + 0.5 );
}
double d = 1.54;
int i = round<int>(d); //explicit <int>
模板
兜圈子(锡五){
回报(兜售)(v+0.5);
}
双d=1.54;
int i=圆形(d)//明确的
我总是必须指定至少一个typename,这是真的吗?我认为原因是因为C++无法区分不同的返回类型之间的函数。 但是,如果我使用void函数并移交引用,我必须再次明确指定返回类型名:

template < typename TOut, typename TIn > 
void round( TOut & vret, TIn vin ) {
   vret = (TOut)(vin + 0.5);
}
   double d = 1.54;
   int i; round(i, d); //no explicit <int>
模板
无效圆(TOut&vret,锡vin){
vret=(TOut)(vin+0.5);
}
双d=1.54;
int i;圆形(i,d)//不明确

结论应该是避免返回函数,而更喜欢编写模板时通过引用返回的
void
函数吗?或者是否有可能避免显式写入返回类型?类似于模板的“类型推断”。在C++0x中“类型推断”是否可能?

重载解析仅基于函数参数进行;根本不使用返回值。如果无法根据参数确定返回类型,则必须显式指定它

我不会通过引用参数“返回”一个值;这使得调用代码不清晰。例如,我更喜欢这样:

double x = round<double>(y);
因为在后一种情况下,很容易混淆输入和输出,而且根本不清楚是否正在修改
x

round
的特定情况下,您可能只需要一到两种类型的
TOut
,因此您可以不使用该模板参数:

template<typename TIn>
int roundToInt(TIn v) {
    return (int)(v + 0.5);
}
模板
内部圆形(锡v){
返回值(整数)(v+0.5);
}
我发现
roundToInt(x)
roundToInt(x)
更清晰一些,因为
int
类型的用途很清楚

结论是避免使用返回函数,而更喜欢编写模板时通过引用返回的void函数

不,为什么?你得到了什么?只进行类型推断(因此要编写的代码更少)。但是,您失去了分配值的更具逻辑性的语法(以及因此而需要编写的更多代码)。所以一件事得到了,另一件事失去了。我看不出总的好处


它甚至可能有助于显式指定模板类型:考虑代码< > ListalyCase的情况。不指定返回模板类型会令人困惑。

让我添加到其他人所说的,你应该更喜欢C++模式下C风格的铸造。

vret = (TOut)(vin + 0.5);

vret = static_cast<TOut>(vin + 0.5);
vret=静态输入(vin+0.5);

如果尝试转换不相关的类型,静态强制转换将始终失败。这有助于调试。

在类型之间进行强制转换会使类型推断的思想变得笨拙,因此您不能重载返回类型,必须在返回类型是模板参数时指定它。您可能需要使用舍入算法。那么-1.54应该是什么呢?并且:如果您想要得到一个四舍五入的双精度值,那么会出现编译时警告/错误,这比在运行时发现要好得多。所涉及的类型必须是什么,以便
静态\u cast
会产生与此模板中的C样式cast不同的结果?(是的,在一个实用函数中,你可能会追求好的风格,但我看不到纯数学代码在数字类型之间进行转换有多大好处——为了保证一篇帖子,也许不是一篇评论。)你可能已经看完了这篇帖子,但我不得不插话。如果使用
静态\u cast
,则错误意味着对象/可执行文件甚至不存在;反之亦然,也就是说,如果您有一个对象/可执行文件,那么您就知道
static_cast
在不同类型之间是有效的。随着您进一步进入模板元编程,您将需要更多地控制其继承树中的类型,例如在CRTP中。关于清晰性:
round_to(x)
?;)@叔叔们,我想说,
roundToInt(x)
roundTo(x)
更清晰,后者比
round(x)
更清晰。也就是说,
roundTo(x)
当然是一个很好的选择,如果您想保持一次性编写模板函数的好处,而不是为每个要舍入的输出类型编写单独的函数,同时仍然能够舍入到多种类型。但是,在大多数情况下,你只舍入到几个类型,我认为
roundToInt(x)
的明确性比让某人舍入到任何类型都好,所以我会选择
roundToInt(x)
(再按照这个模式定义一个或两个以上),除非我需要让某人舍入到几乎任何类型。
vret = static_cast<TOut>(vin + 0.5);