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
#include <iostream>
using namespace std; int operate (int a, int b)
{
return (a*b);
} double operate (double a, double b)
{
return (a/b);
} int main ()
{
int x=,y=;
double n=5.0,m=2.0;
cout << operate (x,y) << '\n';
cout << operate (n,m) << '\n';
return ;
}
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 intparameters, and if it is called with two doubles, it calls the one with two doubles.

In this example, both functions have quite different behaviors, the int version multiplies its arguments, while the doubleversion 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// overloaded functions
#include <iostream>
using namespace std; int sum (int a, int b)
{
return a+b;
} double sum (double a, double b)
{
return a+b;
} int main ()
{
cout << sum (10,20) << '\n';
cout << sum (1.0,1.5) << '\n'
return 0;
}
30
2.5

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:

1
2
3
4
int sum (int a, int b)
{
return a+b;
}

Let's see an actual example:

 
// function template
#include <iostream>
using namespace std; template <class T>
T sum (T a, T b)
{
T result;
result = a + b;
return result;
} int main () {
int i=, j=, k;
double f=2.0, g=0.5, h;
k=sum<int>(i,j);
h=sum<double>(f,g);
cout << k << '\n';
cout << h << '\n';
return ;
}
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:

 
T result;

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:

1
2
k = sum<int> (i,j);
h = sum<double> (f,g);

It is possible to instead simply write:

1
2
k = sum (i,j);
h = sum (f,g);

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
#include <iostream>
using namespace std; template <class T, class U>
bool are_equal (T a, U b)
{
return (a==b);
} int main ()
{
if (are_equal(,10.0))
cout << "x and y are equal\n";
else
cout << "x and y are not equal\n";
return ;
}
x and y are equal

Note that this example uses automatic template parameter deduction in the call to are_equal:

 
are_equal(10,10.0)

Is equivalent to:

 
are_equal<int,double>(10,10.0)

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// template arguments
#include <iostream>
using namespace std; template <class T, int N>
T fixed_multiply (T val)
{
return val * N;
} int main() {
std::cout << fixed_multiply<int,2>(10) << '\n';
std::cout << fixed_multiply<int,3>(10) << '\n';
}
20
30

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的更多相关文章

  1. 解决Windows版Git出现templates not found的问题

    环境: Win10 x64 Git windows客户端(下载自 https://git-scm.com/) SourceTree 1.9.6.1(使用系统安装的Git,而非SourceTree内嵌的 ...

  2. [c++] Templates

    Template是编译时多态.所有的模板都是在编译时产生对应的代码,它没有面向对象中的虚表,无法实现动态多态. Function Template A function template is a p ...

  3. webstrom live templates

    javascript: 在live templates底部要选择javascript # $('#$END$') $ $($end$) $bd $(document.body) $d $(docume ...

  4. Myeclipse Templates详解(一) —— Java模板基础

    目录 Templates简介 MyEclipse自带Templates详解 新建Template 自定义Template 因为自己比较懒,尤其是对敲重复代码比较厌恶,所以经常喜欢用快捷键和模板,Mye ...

  5. Using FreeMarker templates (FTL)- Tutorial

    Lars Vogel, (c) 2012, 2016 vogella GmbHVersion 1.4,06.10.2016 Table of Contents 1. Introduction to F ...

  6. juqery模板 Templates

    现在已经有了许多JavaScript的解决方案模板,从这方面说,标准化的模板解决方案必然是大势所趋.在本节中,我们向你简要描述四个最流行最有趣的模板.现有的模板解决方案能解决什么?那些特色在jQuer ...

  7. django TEMPLATES

    ?: (1_8.W001) The standalone TEMPLATE_* settings were deprecated in Django 1.8 and the TEMPLATES dic ...

  8. django复习笔记3:urls/views/templates三板斧

    0.先看看文件结构 mysite/ mysite/ ├── __pycache__ │   └── manage.cpython-.pyc ├── blog │   ├── __init__.py │ ...

  9. Effective C++ -----条款44:将与参数无关的代码抽离templates

    Templates生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系. 因非类型模板参数(non-type template para ...

随机推荐

  1. birt报表图标中文显示为框框的解决方法

    birt报表中图标部分的中文显示为框框,其他部分中文显示正常 解决办法:修改jdk中的字体设置/jdk1.6.0_13/jre/lib /fonts/fonts.dir 1.将宋体字体copy到/jd ...

  2. HTML5简介、视频

    HTML5 建立的一些规则: 新特性应该基于 HTML.CSS.DOM 以及 JavaScript. 减少对外部插件的需求(比如 Flash) 更优秀的错误处理 更多取代脚本的标记 HTML5 应该独 ...

  3. 一个商品练习的py

    #!/usr/bin/env python # coding=utf-8 # by 星空刺 qian = int(raw_input("请输入当前money:")) gongzi ...

  4. 六度分离--hdu1869

    六度分离 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  5. CART剪枝

    与上篇文章中提到的ID3算法和C4.5算法类似,CART算法也是一种决策树分类算法.CART分类回归树算法的本质也是对数据进行分类的,最终数据的表现形式也是以树形的模式展现的,CART与ID3,C4. ...

  6. Spring Boot 启动加载数据 CommandLineRunner

    实际应用中,我们会有在项目服务启动的时候就去加载一些数据或做一些事情这样的需求. 为了解决这样的问题,Spring Boot 为我们提供了一个方法,通过实现接口 CommandLineRunner 来 ...

  7. MySQL脚本

    一. move.sql use items set @endTime=(select DATE_SUB(now(),INTERVAL 3 MONTH)); REPLACE INTO new_items ...

  8. 关于qt学习的一点小记录(2)

    嗯...这次接了个单 要求图形界面,刚好可以巩固并学习下QT.毫不犹豫的就接了 下面记录下出现的问题: 1. QWidget和QDialog QDialog下的槽函数有accept()与reject( ...

  9. iOS AFNetworking 详解

    1. 很不错的介绍 http://m.blog.csdn.net/blog/jackljf/38736625

  10. AngularJS 2调用.net core WebAPI的几个坑

    前几天,按照AngularJS2的英雄指南教程走了一遍,教程网址是http://origin.angular.live/docs/ts/latest/tutorial/. 在步骤完成后,又更进一步,在 ...