不使用<>调用模板函数; 类型推断

Oli*_*ops 11 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> 
Run Code Online (Sandbox Code Playgroud)

但是,如果我有一个包含两个不同类型名称的函数模板,例如:

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>
Run Code Online (Sandbox Code Playgroud)

我总是必须指定至少1个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>
Run Code Online (Sandbox Code Playgroud)

结论是应该避免使用return和更喜欢void在编写模板时通过引用返回的函数吗?或者是否有可能避免显式写入返回类型?像模板的"类型推断"之类的东西.在C++ 0x中"类型推断"是否可行?

Tho*_*mas 16

重载解析仅基于函数参数完成; 根本没有使用返回值.如果无法根据参数确定返回类型,则必须明确指定它.

我不会沿着通过参考参数"返回"值的路径走下去; 这使得调用代码不清楚.例如,我更喜欢这个:

double x = round<double>(y);
Run Code Online (Sandbox Code Playgroud)

对此:

double x;
round(x, y);
Run Code Online (Sandbox Code Playgroud)

因为在后一种情况下,很容易混淆输入和输出,并且根本不清楚x是否被修改.

在特定情况下round,您可能只需要一种或两种类型TOut,因此您可以将该模板参数保留为:

template<typename TIn>
int roundToInt(TIn v) {
    return (int)(v + 0.5);
}
Run Code Online (Sandbox Code Playgroud)

我发现roundToInt(x)有点清楚,round<int>(x)因为很清楚这种int类型的用途.

  • 关于清晰度:`round_to&lt;int&gt;(x)`?;) (2认同)