如果我有一个带有 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>
但是如果我有一个函数模板有两个不同的类型名,例如:
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>
我总是必须指定至少 1 个类型名,这是真的吗?我认为原因是 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>
结论是否应该避免使用返回函数,而更喜欢在编写时通过引用返回的 void
函数模板?或者是否有可能避免显式编写返回类型?类似于模板的“类型推断”。 C++0x 中可以进行“类型推断”吗?
If I have a function template with typename T
, where the compiler can set the type by itself, I do not have to write the type explicitly when I call the function like:
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>
But if I have a function template with two different typenames like:
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>
Is it true that I always have to specify at least 1 typename? I assume the reason is because C++ can not distinguish functions between different return types.
But if I use a void function and handover a reference, again I must not explicitly specify the return typename:
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>
Should the conclusion be to avoid functions with return and more prefer void
functions that return via a reference when writing templates? Or is there a possibility to avoid explicitly writing the return type? Something like "type inference" for templates. Is "type inference" possible in C++0x?
发布评论
评论(3)
重载解析仅基于函数参数完成;返回值根本没有被使用。如果无法根据参数确定返回类型,则必须显式指定它。
我不会走通过引用参数“返回”值的道路;这使得调用代码不清楚。例如,我更喜欢这样:
而不是这样:
因为在后一种情况下,很容易混淆输入和输出,并且根本不清楚
x
正在被修改。在
round
的特殊情况下,无论如何,您可能只需要一种或两种类型的TOut
,因此您可以将该模板参数排除在外:我发现(x) 更清晰一点,因为
roundToInt( x)
比 roundint
类型的用途很清楚。Overload resolution is done only based on function arguments; the return value is not used at all. If the return type cannot be determined based on the arguments, you will have to specify it explicitly.
I would not go down the path of "returning" a value through a reference parameter; that makes the calling code unclear. For example, I'd prefer this:
over this:
because in the latter case, it's easy to confuse input and output, and it's not at all clear that
x
is being modified.In the particular case of
round
, you probably need only one or two types forTOut
anyway, so you could just leave that template argument out:I find
roundToInt(x)
a little clearer thanround<int>(x)
because it's clear what theint
type is used for.不,为什么?你有什么收获?仅类型推断(因此需要编写的代码更少)。但是您失去了赋值的更逻辑语法(因此需要编写更多代码)。所以得到了一件事,失去了另一件事。我总体上看不出有什么好处。
必须显式指定模板类型甚至可能会有所帮助:考虑 lexical_cast 的情况。不指定返回模板类型会令人困惑。
No, why? What do you gain? Only type inference (so less code to write). But you lose the much more logical syntax of assigning a value (and consequently more code to write). So one thing gained, another lost. I don’t see the benefit in general.
It may even help to have to specify the template type explicitly: consider the case of
lexical_cast
. Not specifying the return template type would be confusing.让我补充一下其他人所说的,你应该更喜欢 C++ 类型转换而不是 C 风格类型转换。
相比
如果您尝试转换不相关的类型,与静态转换 总是会失败。这可以帮助调试。
Let me add to what the others have said by saying you should prefer C++ casting over C-style casting.
versus
static cast will always fail if you try to convert unrelated types. This can help with debugging.