(转) Overloads and templates
Overloaded functions
In C++, two different functions can have the same name if their parameters are different; either because they have a different number of parameters, or because any of their parameters are of a different type. For example:
|
// overloading functions |
2.5 |
In this example, there are two functions called operate
, but one of them has two parameters of type int
, while the other has them of type double
. The compiler knows which one to call in each case by examining the types passed as arguments when the function is called. If it is called with two int
arguments, it calls to the function that has two int
parameters, and if it is called with two double
s, it calls the one with two double
s.
In this example, both functions have quite different behaviors, the int
version multiplies its arguments, while the double
version divides them. This is generally not a good idea. Two functions with the same name are generally expected to have -at least- a similar behavior, but this example demonstrates that is entirely possible for them not to. Two overloaded functions (i.e., two functions with the same name) have entirely different definitions; they are, for all purposes, different functions, that only happen to have the same name.
Note that a function cannot be overloaded only by its return type. At least one of its parameters must have a different type.
Function templates
Overloaded functions may have the same definition. For example:
|
|
30 |
Here, sum
is overloaded with different parameter types, but with the exact same body.
The function sum
could be overloaded for a lot of types, and it could make sense for all of them to have the same body.
For cases such as this, C++ has the ability to define functions with generic types, known as function templates. Defining a function template follows the same syntax than a regular function, except that it is preceded by the template
keyword and a series of template parameters enclosed in angle-brackets <>:
template <template-parameters> function-declaration
The template parameters are a series of parameters separated by commas. These parameters can be generic template types by specifying either the class
or typename
keyword followed by an identifier. This identifier can then be used in the function declaration as if it was a regular type. For example, a generic sum
function could be defined as:
template <class SomeType>
SomeType sum (SomeType a, SomeType b)
{
return a+b;
}
It makes no difference whether the generic type is specified with keyword class
or keyword typename
in the template argument list (they are 100% synonyms in template declarations).
In the code above, declaring SomeType
(a generic type within the template parameters enclosed in angle-brackets) allowsSomeType
to be used anywhere in the function definition, just as any other type; it can be used as the type for parameters, as return type, or to declare new variables of this type. In all cases, it represents a generic type that will be determined on the moment the template is instantiated.
Instantiating a template is applying the template to create a function using particular types or values for its template parameters. This is done by calling the function template, with the same syntax as calling a regular function, but specifying the template arguments enclosed in angle brackets:
name <template-arguments> (function-arguments)
For example, the sum
function template defined above can be called with:
x = sum<int>(,);
The function sum<int>
is just one of the possible instantiations of function template sum
. In this case, by using int
as template argument in the call, the compiler automatically instantiates a version of sum
where each occurrence ofSomeType
is replaced by int
, as if it was defined as:
|
|
Let's see an actual example:
// function template |
2.5 |
In this case, we have used T
as the template parameter name, instead of SomeType
. It makes no difference, and T
is actually a quite common template parameter name for generic types.
In the example above, we used the function template sum
twice. The first time with arguments of type int
, and the second one with arguments of type double
. The compiler has instantiated and then called each time the appropriate version of the function.
Note also how T
is also used to declare a local variable of that (generic) type within sum
:
|
|
Therefore, result will be a variable of the same type as the parameters a
and b
, and as the type returned by the function.
In this specific case where the generic type T
is used as a parameter for sum
, the compiler is even able to deduce the data type automatically without having to explicitly specify it within angle brackets. Therefore, instead of explicitly specifying the template arguments with:
|
|
It is possible to instead simply write:
|
|
without the type enclosed in angle brackets. Naturally, for that, the type shall be unambiguous. If sum
is called with arguments of different types, the compiler may not be able to deduce the type of T
automatically.
Templates are a powerful and versatile feature. They can have multiple template parameters, and the function can still use regular non-templated types. For example:
// function templates |
x and y are equal |
Note that this example uses automatic template parameter deduction in the call to are_equal
:
|
|
Is equivalent to:
|
|
Since, in C++, integer literals with no suffix (such as 10
) are always of type int
, and floating-point literals without suffix (such as 10.0
) are always of type double
, there is no ambiguity possible, and thus the template arguments can be omitted in the call.
Non-type template arguments
The template parameters can not only include types introduced by class
or typename
, but can also include expressions of a particular type:
|
|
20 |
The second argument of the fixed_multiply
function template is of type int
. It just looks like a regular function parameter, and can actually be used just like one.
But there exists a major difference: the value of template parameters is determined on compile-time to generate a different instantiation of the function fixed_multiply
, and thus the value of that argument is never passed during runtime: The two calls to fixed_multiply
in main
essentially call two versions of the function: one that always multiplies by two, and one that always multiplies by three. For that same reason, the second template argument needs to be a constant expression (it cannot be passed a variable).
(转) Overloads and templates的更多相关文章
- 解决Windows版Git出现templates not found的问题
环境: Win10 x64 Git windows客户端(下载自 https://git-scm.com/) SourceTree 1.9.6.1(使用系统安装的Git,而非SourceTree内嵌的 ...
- [c++] Templates
Template是编译时多态.所有的模板都是在编译时产生对应的代码,它没有面向对象中的虚表,无法实现动态多态. Function Template A function template is a p ...
- webstrom live templates
javascript: 在live templates底部要选择javascript # $('#$END$') $ $($end$) $bd $(document.body) $d $(docume ...
- Myeclipse Templates详解(一) —— Java模板基础
目录 Templates简介 MyEclipse自带Templates详解 新建Template 自定义Template 因为自己比较懒,尤其是对敲重复代码比较厌恶,所以经常喜欢用快捷键和模板,Mye ...
- Using FreeMarker templates (FTL)- Tutorial
Lars Vogel, (c) 2012, 2016 vogella GmbHVersion 1.4,06.10.2016 Table of Contents 1. Introduction to F ...
- juqery模板 Templates
现在已经有了许多JavaScript的解决方案模板,从这方面说,标准化的模板解决方案必然是大势所趋.在本节中,我们向你简要描述四个最流行最有趣的模板.现有的模板解决方案能解决什么?那些特色在jQuer ...
- django TEMPLATES
?: (1_8.W001) The standalone TEMPLATE_* settings were deprecated in Django 1.8 and the TEMPLATES dic ...
- django复习笔记3:urls/views/templates三板斧
0.先看看文件结构 mysite/ mysite/ ├── __pycache__ │ └── manage.cpython-.pyc ├── blog │ ├── __init__.py │ ...
- Effective C++ -----条款44:将与参数无关的代码抽离templates
Templates生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系. 因非类型模板参数(non-type template para ...
随机推荐
- asp.net FileUpload 控件上传文件 以二进制的形式存入数据库并将图片显示出来
图片上传事件代码如下所示: byte[] binary = upload.FileBytes; StringBuilder sqlStrSb = new StringBuilder(); sqlStr ...
- MYSQL 磁盘临时表和文件排序
因为Memory引擎不支持BOLB和TEXT类型,所以,如果查询使用了BLOB或TEXT列并且需要使用隐式临时表,将不得不使用MyISAM磁盘临时表,即使只有几行数据也是如此. 这会导致严重的性能开销 ...
- jQuery输入框提示自动完成插件 autocomplete
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 01--从根源种子CCNode说起
CCNode作为渲染框架的基类(暂且这样理解,CCObject为引擎基类)其中定义了绘制游戏元素相关的属性以及相关方法.属性当中需要注意的一个是Z坐标,在渲染框架中用来表示元素的遮挡关系,其值越小越容 ...
- 【笔记】Unix 平台标准
POSIX 表示可移植操作系统接口(Portable Operating System Interface ,缩写为 POSIX ),POSIX标准定义了操作系统应该为应用程序提供的接口标准,是IEE ...
- CSU 1335 高桥和低桥
开始队友说是线段树,看了看貌似也是,上手敲了个嵌套的线段树,O(nlognlogn)的复杂度果断tle了 TAT 思路:对h[i]排序,对每次涨水退水,先用二分查找,再用一个数组保存当前点之后所有点被 ...
- scala学习笔记-类型参数中协变(+)、逆变(-)、类型上界(<:)和类型下界(>:)的使用
转载自 fineqtbull http://fineqtbull.iteye.com/blog/477994 有位je上的同学来短信向我问起了Scala类型参数中协变.逆变.类型上界和类型下界的 ...
- 如何在Latex上裁减图片
在Latex的使用过程中,很多人需要载入一些具有一定白边或者边框的图片.特别是用matlab生成的很多图片.大部分人的做法是通过使用pdf工具去裁减.这样做很麻烦,并且对于一些批量的,大小相同的图片而 ...
- C51汇编伪指令
1.DS ---预留存储区命令格式: [标号:] DS 表达式值其功能是从指定地址开始,定义一个存储区,以备源程序使用.存储区预留的存储单元数由表达式的值决定. ;从标号TEP地址处开始保留1个存 ...
- 选择排序(Selection Sort)
选择排序就是在选择数组元素上做文章,关键是如何选择?选择的标准是什么?选择之后放在哪?所有这些都是选择排序的问题. 选择排序算法中,通常会有以下操作: 从数组第一个元素开始. 遍历整个数组,找到最小的 ...