C++ 不带<>调用模板函数;类型推断
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2833730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling template function without <>; type inference
提问by OlimilOops
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:
如果我有一个带有 的函数模板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>
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.
我总是必须至少指定 1 个类型名,这是真的吗?我假设原因是因为 C++ 无法区分不同返回类型之间的函数。
But if I use a void function and handover a reference, again I must not explicitly specify the return typename:
但是,如果我使用 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>
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?
结论应该是避免带返回的void
函数,更喜欢在编写模板时通过引用返回的函数吗?或者是否有可能避免显式编写返回类型?类似于模板的“类型推断”。在 C++0x 中可以进行“类型推断”吗?
回答by Thomas
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:
我不会走通过引用参数“返回”值的路径;这使得调用代码不清楚。例如,我更喜欢这个:
double x = round<double>(y);
over this:
在这个:
double x;
round(x, y);
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.
因为在后一种情况下,很容易混淆输入和输出,并且根本不清楚x
正在修改。
In the particular case of round
, you probably need only one or two types for TOut
anyway, so you could just leave that template argument out:
在 的特殊情况下round
,无论如何您可能只需要一两种类型TOut
,因此您可以将该模板参数排除在外:
template<typename TIn>
int roundToInt(TIn v) {
return (int)(v + 0.5);
}
I find roundToInt(x)
a little clearer than round<int>(x)
because it's clear what the int
type is used for.
我觉得roundToInt(x)
更清楚一点,round<int>(x)
因为它很清楚int
类型的用途。
回答by Konrad Rudolph
the conclusion be to avoid functions with return and more prefer void functions that return via a reference when writing templates
结论是避免带返回的函数,更喜欢在编写模板时通过引用返回的 void 函数
No, why? What do you gain? Only type inference (so less code to write). But you losethe 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 helpto have to specify the template type explicitly: consider the case of lexical_cast
. Not specifying the return template type would be confusing.
必须明确指定模板类型甚至可能会有所帮助:考虑lexical_cast
. 不指定返回模板类型会令人困惑。
回答by wheaties
Let me add to what the others have said by saying you should prefer C++ casting over C-style casting.
让我补充一下其他人所说的,说您应该更喜欢 C++ 类型转换而不是 C 风格转换。
vret = (TOut)(vin + 0.5);
versus
相对
vret = static_cast<TOut>(vin + 0.5);
static cast will always fail if you try to convert unrelated types. This can help with debugging.
如果您尝试转换不相关的类型,静态转换将始终失败。这有助于调试。